summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>2007-10-07 11:44:33 +0000
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>2007-10-07 11:44:33 +0000
commit653831d0e66104c8934f42dfd5232515d70637f4 (patch)
tree1971111a55f1b3ae34603f33cccfb8e2508c1b44
parent4e3ecaa575f12608e3833399c5eddec5d6c3e522 (diff)
[svn-upgrade] Tagging new upstream version, shadow (20000902)20000902
-rw-r--r--current/ABOUT-NLS226
-rw-r--r--current/Makefile.am6
-rw-r--r--current/Makefile.in391
-rw-r--r--current/acconfig.h151
-rw-r--r--current/aclocal.m41027
-rwxr-xr-xcurrent/config.guess1087
-rw-r--r--current/config.h.in460
-rwxr-xr-xcurrent/config.sub1215
-rwxr-xr-xcurrent/configure6803
-rw-r--r--current/configure.in311
-rw-r--r--current/contrib/Makefile.am6
-rw-r--r--current/contrib/Makefile.in212
-rw-r--r--current/contrib/README10
-rw-r--r--current/contrib/adduser-old.c300
-rw-r--r--current/contrib/adduser.c502
-rwxr-xr-xcurrent/contrib/adduser.sh90
-rwxr-xr-xcurrent/contrib/adduser2.sh743
-rwxr-xr-xcurrent/contrib/atudel85
-rw-r--r--current/contrib/groupmems.shar546
-rw-r--r--current/contrib/pwdauth.c308
-rw-r--r--current/contrib/rpasswd.c591
-rw-r--r--current/contrib/shadow-anonftp.patch147
-rw-r--r--current/contrib/udbachk.v012.tgzbin0 -> 20228 bytes
-rw-r--r--current/debian/FILES70
-rw-r--r--current/debian/Makefile.am9
-rw-r--r--current/debian/Makefile.in212
-rw-r--r--current/debian/changelog175
-rwxr-xr-xcurrent/debian/checksums7
-rw-r--r--current/debian/control41
-rw-r--r--current/debian/control.gnu16
-rw-r--r--current/debian/control.linux41
-rw-r--r--current/debian/login.conffiles6
-rw-r--r--current/debian/login.copyright76
-rw-r--r--current/debian/login.postinst42
-rw-r--r--current/debian/login.postrm6
-rw-r--r--current/debian/login.preinst4
-rw-r--r--current/debian/login.prerm8
-rw-r--r--current/debian/logoutd.init36
-rw-r--r--current/debian/passwd.conffiles3
-rw-r--r--current/debian/passwd.copyright55
-rw-r--r--current/debian/passwd.cron8
-rwxr-xr-xcurrent/debian/passwd.init25
-rw-r--r--current/debian/passwd.postinst41
-rw-r--r--current/debian/passwd.postrm6
-rw-r--r--current/debian/porttime8
-rwxr-xr-xcurrent/debian/rules159
-rw-r--r--current/debian/secure-su.README4
-rw-r--r--current/debian/secure-su.conffiles1
-rw-r--r--current/debian/secure-su.copyright54
-rw-r--r--current/debian/secure-su.postrm12
-rw-r--r--current/debian/secure-su.preinst14
-rw-r--r--current/debian/securetty14
-rw-r--r--current/debian/tar.c409
-rw-r--r--current/doc/ANNOUNCE48
-rw-r--r--current/doc/CHANGES694
-rw-r--r--current/doc/HOWTO1918
-rw-r--r--current/doc/INSTALL176
-rw-r--r--current/doc/LICENSE118
-rw-r--r--current/doc/LSM20
-rw-r--r--current/doc/Makefile.am7
-rw-r--r--current/doc/Makefile.in212
-rw-r--r--current/doc/README253
-rw-r--r--current/doc/README.debian68
-rw-r--r--current/doc/README.limits66
-rw-r--r--current/doc/README.linux166
-rw-r--r--current/doc/README.mirrors60
-rw-r--r--current/doc/README.nls30
-rw-r--r--current/doc/README.pam35
-rw-r--r--current/doc/README.platforms33
-rw-r--r--current/doc/README.shadow-paper25
-rw-r--r--current/doc/README.sun439
-rw-r--r--current/doc/WISHLIST53
-rw-r--r--current/doc/console.c.spec.txt36
-rw-r--r--current/doc/cracklib26.diff340
-rw-r--r--current/etc/Makefile.am7
-rw-r--r--current/etc/Makefile.in318
-rw-r--r--current/etc/limits28
-rw-r--r--current/etc/login.access54
-rw-r--r--current/etc/login.defs214
-rw-r--r--current/etc/login.defs.hurd143
-rw-r--r--current/etc/login.defs.linux370
-rw-r--r--current/etc/pam.d/Makefile.am4
-rw-r--r--current/etc/pam.d/Makefile.in211
-rw-r--r--current/etc/pam.d/passwd5
-rw-r--r--current/etc/pam.d/su7
-rw-r--r--current/etc/shells10
-rw-r--r--current/etc/suauth4
-rwxr-xr-xcurrent/install-sh251
-rw-r--r--current/intl/ChangeLog1086
-rw-r--r--current/intl/Makefile.in214
-rw-r--r--current/intl/VERSION1
-rw-r--r--current/intl/bindtextdom.c203
-rw-r--r--current/intl/cat-compat.c262
-rw-r--r--current/intl/dcgettext.c655
-rw-r--r--current/intl/dgettext.c59
-rw-r--r--current/intl/explodename.c197
-rw-r--r--current/intl/finddomain.c216
-rw-r--r--current/intl/gettext.c70
-rw-r--r--current/intl/gettext.h105
-rw-r--r--current/intl/gettextP.h89
-rw-r--r--current/intl/hash-string.h59
-rw-r--r--current/intl/intl-compat.c76
-rw-r--r--current/intl/l10nflist.c411
-rw-r--r--current/intl/libgettext.h182
-rw-r--r--current/intl/linux-msg.sed100
-rw-r--r--current/intl/loadinfo.h78
-rw-r--r--current/intl/loadmsgcat.c220
-rw-r--r--current/intl/localealias.c438
-rw-r--r--current/intl/po2tbl.sed.in102
-rw-r--r--current/intl/textdomain.c108
-rw-r--r--current/intl/xopen-msg.sed104
-rw-r--r--current/lib/Makefile.am57
-rw-r--r--current/lib/Makefile.in448
-rw-r--r--current/lib/commonio.c803
-rw-r--r--current/lib/commonio.h100
-rw-r--r--current/lib/defines.h348
-rw-r--r--current/lib/dialchk.c77
-rw-r--r--current/lib/dialchk.h16
-rw-r--r--current/lib/dialup.c169
-rw-r--r--current/lib/dialup.h66
-rw-r--r--current/lib/encrypt.c123
-rw-r--r--current/lib/faillog.h55
-rw-r--r--current/lib/fputsx.c80
-rw-r--r--current/lib/getdef.c406
-rw-r--r--current/lib/getdef.h11
-rw-r--r--current/lib/getpass.c296
-rw-r--r--current/lib/grdbm.c211
-rw-r--r--current/lib/groupio.c184
-rw-r--r--current/lib/groupio.h12
-rw-r--r--current/lib/grpack.c95
-rw-r--r--current/lib/gsdbm.c167
-rw-r--r--current/lib/gshadow.c528
-rw-r--r--current/lib/gshadow_.h71
-rw-r--r--current/lib/gspack.c150
-rw-r--r--current/lib/lastlog_.h50
-rw-r--r--current/lib/lockpw.c114
-rw-r--r--current/lib/md5.c261
-rw-r--r--current/lib/md5.h27
-rw-r--r--current/lib/md5crypt.c151
-rw-r--r--current/lib/mkdir.c60
-rw-r--r--current/lib/pam_defs.h21
-rw-r--r--current/lib/port.c439
-rw-r--r--current/lib/port.h81
-rw-r--r--current/lib/prototypes.h228
-rw-r--r--current/lib/putgrent.c75
-rw-r--r--current/lib/putpwent.c72
-rw-r--r--current/lib/putspent.c103
-rw-r--r--current/lib/pwauth.c578
-rw-r--r--current/lib/pwauth.h60
-rw-r--r--current/lib/pwdbm.c143
-rw-r--r--current/lib/pwio.c186
-rw-r--r--current/lib/pwio.h12
-rw-r--r--current/lib/pwpack.c163
-rw-r--r--current/lib/rad64.c126
-rw-r--r--current/lib/rcsid.h22
-rw-r--r--current/lib/rename.c91
-rw-r--r--current/lib/rmdir.c59
-rw-r--r--current/lib/sgetgrent.c140
-rw-r--r--current/lib/sgetpwent.c136
-rw-r--r--current/lib/sgetspent.c198
-rw-r--r--current/lib/sgroupio.c212
-rw-r--r--current/lib/sgroupio.h13
-rw-r--r--current/lib/shadow.c592
-rw-r--r--current/lib/shadow_.h89
-rw-r--r--current/lib/shadowio.c171
-rw-r--r--current/lib/shadowio.h13
-rw-r--r--current/lib/snprintf.c320
-rw-r--r--current/lib/snprintf.h51
-rw-r--r--current/lib/spdbm.c116
-rw-r--r--current/lib/sppack.c113
-rw-r--r--current/lib/strcasecmp.c25
-rw-r--r--current/lib/strdup.c16
-rw-r--r--current/lib/strerror.c23
-rw-r--r--current/lib/strstr.c55
-rw-r--r--current/lib/tcfsio.c90
-rw-r--r--current/lib/tcfsio.h14
-rw-r--r--current/lib/utent.c114
-rw-r--r--current/libmisc/Makefile.am20
-rw-r--r--current/libmisc/Makefile.in435
-rw-r--r--current/libmisc/addgrps.c89
-rw-r--r--current/libmisc/age.c235
-rw-r--r--current/libmisc/basename.c22
-rw-r--r--current/libmisc/chkname.c73
-rw-r--r--current/libmisc/chkname.h15
-rw-r--r--current/libmisc/chkshell.c98
-rw-r--r--current/libmisc/chowndir.c132
-rw-r--r--current/libmisc/chowntty.c127
-rw-r--r--current/libmisc/console.c115
-rw-r--r--current/libmisc/copydir.c403
-rw-r--r--current/libmisc/entry.c99
-rw-r--r--current/libmisc/env.c250
-rw-r--r--current/libmisc/failure.c278
-rw-r--r--current/libmisc/failure.h44
-rw-r--r--current/libmisc/fields.c104
-rw-r--r--current/libmisc/getdate.c2006
-rw-r--r--current/libmisc/getdate.h8
-rw-r--r--current/libmisc/getdate.y1024
-rw-r--r--current/libmisc/hushed.c90
-rw-r--r--current/libmisc/isexpired.c173
-rw-r--r--current/libmisc/limits.c426
-rw-r--r--current/libmisc/list.c234
-rw-r--r--current/libmisc/log.c100
-rw-r--r--current/libmisc/login_access.c340
-rw-r--r--current/libmisc/login_desrpc.c77
-rw-r--r--current/libmisc/login_krb.c61
-rw-r--r--current/libmisc/loginprompt.c165
-rw-r--r--current/libmisc/mail.c79
-rw-r--r--current/libmisc/motd.c69
-rw-r--r--current/libmisc/myname.c41
-rw-r--r--current/libmisc/obscure.c286
-rw-r--r--current/libmisc/pam_pass.c58
-rw-r--r--current/libmisc/pwd2spwd.c103
-rw-r--r--current/libmisc/pwd_init.c73
-rw-r--r--current/libmisc/pwdcheck.c69
-rw-r--r--current/libmisc/rlogin.c171
-rw-r--r--current/libmisc/salt.c70
-rw-r--r--current/libmisc/setugid.c134
-rw-r--r--current/libmisc/setup.c72
-rw-r--r--current/libmisc/setupenv.c292
-rw-r--r--current/libmisc/shell.c126
-rw-r--r--current/libmisc/strtoday.c207
-rw-r--r--current/libmisc/suauth.c201
-rw-r--r--current/libmisc/sub.c78
-rw-r--r--current/libmisc/sulog.c74
-rw-r--r--current/libmisc/ttytype.c89
-rw-r--r--current/libmisc/tz.c67
-rw-r--r--current/libmisc/ulimit.c34
-rw-r--r--current/libmisc/utmp.c478
-rw-r--r--current/libmisc/valid.c101
-rw-r--r--current/libmisc/xmalloc.c38
-rwxr-xr-xcurrent/ltconfig3017
-rw-r--r--current/ltmain.sh3975
-rw-r--r--current/man/Makefile.am21
-rw-r--r--current/man/Makefile.in471
-rw-r--r--current/man/chage.1109
-rw-r--r--current/man/chfn.166
-rw-r--r--current/man/chpasswd.862
-rw-r--r--current/man/chsh.166
-rw-r--r--current/man/dialups.522
-rw-r--r--current/man/dpasswd.855
-rw-r--r--current/man/faillog.559
-rw-r--r--current/man/faillog.8100
-rw-r--r--current/man/gpasswd.173
-rw-r--r--current/man/groupadd.864
-rw-r--r--current/man/groupdel.860
-rw-r--r--current/man/groupmod.866
-rw-r--r--current/man/groups.157
-rw-r--r--current/man/grpck.8101
-rw-r--r--current/man/id.154
-rw-r--r--current/man/lastlog.863
-rw-r--r--current/man/limits.576
-rw-r--r--current/man/login.1155
-rw-r--r--current/man/login.access.552
-rw-r--r--current/man/login.defs.5573
-rw-r--r--current/man/logoutd.851
-rw-r--r--current/man/mkpasswd.881
-rw-r--r--current/man/newgrp.180
-rw-r--r--current/man/newusers.868
-rw-r--r--current/man/passwd.1190
-rw-r--r--current/man/passwd.5111
-rw-r--r--current/man/pl/Makefile.am60
-rw-r--r--current/man/pl/Makefile.in316
-rw-r--r--current/man/pl/chage.1110
-rw-r--r--current/man/pl/chfn.177
-rw-r--r--current/man/pl/chpasswd.862
-rw-r--r--current/man/pl/chsh.170
-rw-r--r--current/man/pl/d_passwd.530
-rw-r--r--current/man/pl/dialups.524
-rw-r--r--current/man/pl/dpasswd.856
-rw-r--r--current/man/pl/faillog.559
-rw-r--r--current/man/pl/faillog.895
-rw-r--r--current/man/pl/gpasswd.165
-rw-r--r--current/man/pl/groupadd.872
-rw-r--r--current/man/pl/groupdel.868
-rw-r--r--current/man/pl/groupmod.877
-rw-r--r--current/man/pl/groups.161
-rw-r--r--current/man/pl/grpck.8103
-rw-r--r--current/man/pl/id.157
-rw-r--r--current/man/pl/lastlog.864
-rw-r--r--current/man/pl/limits.579
-rw-r--r--current/man/pl/login.1134
-rw-r--r--current/man/pl/login.access.554
-rw-r--r--current/man/pl/login.defs.5557
-rw-r--r--current/man/pl/logoutd.850
-rw-r--r--current/man/pl/mkpasswd.880
-rw-r--r--current/man/pl/newgrp.187
-rw-r--r--current/man/pl/newusers.869
-rw-r--r--current/man/pl/passwd.1201
-rw-r--r--current/man/pl/passwd.588
-rw-r--r--current/man/pl/porttime.581
-rw-r--r--current/man/pl/pw_auth.3152
-rw-r--r--current/man/pl/pwauth.865
-rw-r--r--current/man/pl/pwck.8109
-rw-r--r--current/man/pl/pwconv.866
-rw-r--r--current/man/pl/shadow.3148
-rw-r--r--current/man/pl/shadow.592
-rw-r--r--current/man/pl/shadowconfig.827
-rw-r--r--current/man/pl/su.187
-rw-r--r--current/man/pl/suauth.5115
-rw-r--r--current/man/pl/sulogin.894
-rw-r--r--current/man/porttime.584
-rw-r--r--current/man/pw_auth.3159
-rw-r--r--current/man/pwauth.867
-rw-r--r--current/man/pwck.8107
-rw-r--r--current/man/pwconv.863
-rw-r--r--current/man/shadow.3148
-rw-r--r--current/man/shadow.599
-rw-r--r--current/man/shadowconfig.824
-rw-r--r--current/man/su.187
-rw-r--r--current/man/suauth.5112
-rw-r--r--current/man/sulogin.888
-rw-r--r--current/man/useradd.8197
-rw-r--r--current/man/userdel.869
-rw-r--r--current/man/usermod.8162
-rw-r--r--current/man/vipw.829
-rwxr-xr-xcurrent/missing190
-rwxr-xr-xcurrent/mkinstalldirs40
-rw-r--r--current/po/ChangeLog0
-rw-r--r--current/po/Makefile.in.in248
-rw-r--r--current/po/POTFILES.in123
-rw-r--r--current/po/cat-id-tbl.c504
-rw-r--r--current/po/el.gmobin0 -> 41822 bytes
-rw-r--r--current/po/el.po2459
-rw-r--r--current/po/fr.gmobin0 -> 40067 bytes
-rw-r--r--current/po/fr.po2417
-rw-r--r--current/po/pl.gmobin0 -> 40513 bytes
-rw-r--r--current/po/pl.po2414
-rw-r--r--current/po/shadow.pot2368
-rw-r--r--current/po/stamp-cat-id1
-rw-r--r--current/po/sv.gmobin0 -> 39254 bytes
-rw-r--r--current/po/sv.po2406
-rw-r--r--current/redhat/Makefile.am8
-rw-r--r--current/redhat/Makefile.in214
-rw-r--r--current/redhat/README29
-rw-r--r--current/redhat/shadow-970616-fix.patch256
-rw-r--r--current/redhat/shadow-970616-glibc.patch11
-rw-r--r--current/redhat/shadow-970616-rh.patch1242
-rw-r--r--current/redhat/shadow-970616-utuser.patch12
-rw-r--r--current/redhat/shadow-970616.login.defs57
-rw-r--r--current/redhat/shadow-970616.useradd7
-rw-r--r--current/redhat/shadow-utils-970616.spec137
-rw-r--r--current/redhat/shadow-utils.spec.in154
-rw-r--r--current/src/Makefile.am90
-rw-r--r--current/src/Makefile.in895
-rw-r--r--current/src/chage.c841
-rw-r--r--current/src/chfn.c600
-rw-r--r--current/src/chpasswd.c288
-rw-r--r--current/src/chsh.c437
-rw-r--r--current/src/dpasswd.c259
-rw-r--r--current/src/expiry.c210
-rw-r--r--current/src/faillog.c379
-rw-r--r--current/src/gpasswd.c661
-rw-r--r--current/src/groupadd.c537
-rw-r--r--current/src/groupdel.c351
-rw-r--r--current/src/groupmod.c548
-rw-r--r--current/src/groups.c183
-rw-r--r--current/src/grpck.c649
-rw-r--r--current/src/grpconv.c173
-rw-r--r--current/src/grpunconv.c131
-rw-r--r--current/src/id.c187
-rw-r--r--current/src/lastlog.c192
-rw-r--r--current/src/login.c1314
-rw-r--r--current/src/logoutd.c308
-rw-r--r--current/src/mkpasswd.c394
-rw-r--r--current/src/newgrp.c499
-rw-r--r--current/src/newusers.c568
-rw-r--r--current/src/passwd.c1415
-rw-r--r--current/src/patchlevel.h58
-rw-r--r--current/src/pwck.c616
-rw-r--r--current/src/pwconv.c187
-rw-r--r--current/src/pwunconv.c196
-rwxr-xr-xcurrent/src/shadowconfig.sh67
-rw-r--r--current/src/su.c637
-rw-r--r--current/src/sulogin.c273
-rw-r--r--current/src/useradd.c1746
-rw-r--r--current/src/userdel.c846
-rw-r--r--current/src/usermod.c1705
-rw-r--r--current/src/vipw.c252
-rw-r--r--current/stamp-h.in1
379 files changed, 97630 insertions, 0 deletions
diff --git a/current/ABOUT-NLS b/current/ABOUT-NLS
new file mode 100644
index 00000000..28d38c76
--- /dev/null
+++ b/current/ABOUT-NLS
@@ -0,0 +1,226 @@
+Notes on the Free Translation Project
+*************************************
+
+ Free software is going international! The Free Translation Project
+is a way to get maintainers of free software, translators, and users all
+together, so that will gradually become able to speak many languages.
+A few packages already provide translations for their messages.
+
+ If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site. But you do *not*
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+ Installers will find here some useful hints. These notes also
+explain how users should proceed for getting the programs to use the
+available translations. They tell how people wanting to contribute and
+work at translations should contact the appropriate team.
+
+ When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used. The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+One advise in advance
+=====================
+
+ If you want to exploit the full power of internationalization, you
+should configure it using
+
+ ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed. So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias or message inheritance) as the
+implementation here. It is also not possible to offer this additional
+functionality on top of a `catgets' implementation. Future versions of
+GNU `gettext' will very likely convey even more functionality. So it
+might be a good idea to change to GNU `gettext' as soon as possible.
+
+ So you need not provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+INSTALL Matters
+===============
+
+ Some packages are "localizable" when properly installed; the
+programs they contain can be made to speak your own native language.
+Most such packages use GNU `gettext'. Other packages have their own
+ways to internationalization, predating GNU `gettext'.
+
+ By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system provides
+usable `catgets' (if using this is selected by the installer) or
+`gettext' functions. If neither is available, the GNU `gettext' own
+library will be used. This library is wholly contained within this
+package, usually in the `intl/' subdirectory, so prior installation of
+the GNU `gettext' package is *not* required. Installers may use
+special options at configuration time for changing the default
+behaviour. The commands:
+
+ ./configure --with-included-gettext
+ ./configure --with-catgets
+ ./configure --disable-nls
+
+will respectively bypass any pre-existing `catgets' or `gettext' to use
+the internationalizing routines provided within this package, enable
+the use of the `catgets' functions (if found on the locale system), or
+else, *totally* disable translation of messages.
+
+ When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this. This might be not what is desirable. You
+should use the more recent version of the GNU `gettext' library. I.e.
+if the file `intl/VERSION' shows that the library which comes with this
+package is more recent, you should use
+
+ ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+ By default the configuration process will not test for the `catgets'
+function and therefore they will not be used. The reasons are already
+given above: the emulation on top of `catgets' cannot provide all the
+extensions provided by the GNU `gettext' library. If you nevertheless
+want to use the `catgets' functions use
+
+ ./configure --with-catgets
+
+to enable the test for `catgets' (this causes no harm if `catgets' is
+not available on your system). If you really select this option we
+would like to hear about the reasons because we cannot think of any
+good one ourself.
+
+ Internationalized packages have usually many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language. Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package. However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+Using This Package
+==================
+
+ As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+ISO 639 `LL' two-letter code prior to using the programs in the
+package. For example, let's suppose that you speak German. At the
+shell prompt, merely execute `setenv LANG de' (in `csh'),
+`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This
+can be done from your `.login' or `.profile' file, once and for all.
+
+ An operating system might already offer message localization for
+many of its programs, while other programs have been installed locally
+with the full capabilities of GNU `gettext'. Just using `gettext'
+extended syntax for `LANG' would break proper localization of already
+available operating system programs. In this case, users should set
+both `LANGUAGE' and `LANG' variables in their environment, as programs
+using GNU `gettext' give preference to `LANGUAGE'. For example, some
+Swedish users would rather read translations in German than English for
+when Swedish is not available. This is easily accomplished by setting
+`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'.
+
+Translating Teams
+=================
+
+ For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list, courtesy of Linux
+International. You may reach your translation team at the address
+`LL@li.org', replacing LL by the two-letter ISO 639 code for your
+language. Language codes are *not* the same as the country codes given
+in ISO 3166. The following translation teams exist, as of December
+1997:
+
+ Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en',
+ Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian
+ `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja',
+ Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish
+ `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es',
+ Swedish `sv', and Turkish `tr'.
+
+For example, you may reach the Chinese translation team by writing to
+`zh@li.org'.
+
+ If you'd like to volunteer to *work* at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is *not* the same as the list itself, it has
+`-request' appended. For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+ subscribe
+
+ Keep in mind that team members are expected to participate
+*actively* in translations, or at solving translational difficulties,
+rather than merely lurking around. If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `translation@iro.umontreal.ca' to reach the
+coordinator for all translator teams.
+
+ The English team is special. It works at improving and uniformizing
+the terminology in use. Proven linguistic skill are praised more than
+programming skill, here.
+
+Available Packages
+==================
+
+ Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of December
+1997. The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination.
+
+ Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv
+ .----------------------------------------------------.
+ bash | [] [] [] | 3
+ bison | [] [] [] | 3
+ clisp | [] [] [] [] | 4
+ cpio | [] [] [] [] [] [] | 6
+ diffutils | [] [] [] [] [] | 5
+ enscript | [] [] [] [] [] [] | 6
+ fileutils | [] [] [] [] [] [] [] [] [] [] | 10
+ findutils | [] [] [] [] [] [] [] [] [] | 9
+ flex | [] [] [] [] | 4
+ gcal | [] [] [] [] [] | 5
+ gettext | [] [] [] [] [] [] [] [] [] [] [] | 12
+ grep | [] [] [] [] [] [] [] [] [] [] | 10
+ hello | [] [] [] [] [] [] [] [] [] [] [] | 11
+ id-utils | [] [] [] | 3
+ indent | [] [] [] [] [] | 5
+ libc | [] [] [] [] [] [] [] | 7
+ m4 | [] [] [] [] [] [] | 6
+ make | [] [] [] [] [] [] | 6
+ music | [] [] | 2
+ ptx | [] [] [] [] [] [] [] [] | 8
+ recode | [] [] [] [] [] [] [] [] [] | 9
+ sh-utils | [] [] [] [] [] [] [] [] | 8
+ sharutils | [] [] [] [] [] [] | 6
+ tar | [] [] [] [] [] [] [] [] [] [] [] | 11
+ texinfo | [] [] [] | 3
+ textutils | [] [] [] [] [] [] [] [] [] | 9
+ wdiff | [] [] [] [] [] [] [] [] | 8
+ `----------------------------------------------------'
+ 17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv
+ 27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179
+
+ Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect. This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+ For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer. There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+ If December 1997 seems to be old, you may fetch a more recent copy
+of this `ABOUT-NLS' file on most GNU archive sites.
+
diff --git a/current/Makefile.am b/current/Makefile.am
new file mode 100644
index 00000000..36b1db1e
--- /dev/null
+++ b/current/Makefile.am
@@ -0,0 +1,6 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+SUBDIRS = intl po man lib libmisc src \
+ contrib debian doc etc redhat # old
diff --git a/current/Makefile.in b/current/Makefile.in
new file mode 100644
index 00000000..b608fad7
--- /dev/null
+++ b/current/Makefile.in
@@ -0,0 +1,391 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+SUBDIRS = intl po man lib libmisc src contrib debian doc etc redhat # old
+
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = ./stamp-h.in ABOUT-NLS Makefile.am Makefile.in acconfig.h \
+aclocal.m4 config.guess config.h.in config.sub configure configure.in \
+install-sh ltconfig ltmain.sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+install-data-recursive uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/acconfig.h b/current/acconfig.h
new file mode 100644
index 00000000..7fce8825
--- /dev/null
+++ b/current/acconfig.h
@@ -0,0 +1,151 @@
+/* $Id: acconfig.h,v 1.13 1999/08/27 19:02:50 marekm Exp $ */
+
+
+
+/* Define to enable password aging. */
+#undef AGING
+
+/* Define if struct passwd has pw_age. */
+#undef ATT_AGE
+
+/* Define if struct passwd has pw_comment. */
+#undef ATT_COMMENT
+
+/* Define to support JFH's auth. methods. UNTESTED. */
+#undef AUTH_METHODS
+
+/* Define if struct passwd has pw_quota. */
+#undef BSD_QUOTA
+
+/* Define if you have secure RPC. */
+#undef DES_RPC
+
+/* Define to support 16-character passwords. */
+#undef DOUBLESIZE
+
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Path for faillog file. */
+#undef FAILLOG_FILE
+
+/* Define if you want my getgrent routines. */
+#undef GETGRENT
+
+/* Define to libshadow_getpass to use our own version of getpass(). */
+#undef getpass
+
+/* Define if you want my getpwent routines. */
+#undef GETPWENT
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Defined if you have libcrack. */
+#undef HAVE_LIBCRACK
+
+/* Defined if you have the ts&szs cracklib. */
+#undef HAVE_LIBCRACK_HIST
+
+/* Defined if it includes *Pw functions. */
+#undef HAVE_LIBCRACK_PW
+
+/* Defined if you have libcrypt. */
+#undef HAVE_LIBCRYPT
+
+/* Define if struct lastlog has ll_host */
+#undef HAVE_LL_HOST
+
+/* Working shadow group support in libc? */
+#undef HAVE_SHADOWGRP
+
+/* Define to 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define to support TCFS. */
+#undef HAVE_TCFS
+
+/* Path for lastlog file. */
+#undef LASTLOG_FILE
+
+/* Define to support /etc/login.access login access control. */
+#undef LOGIN_ACCESS
+
+/* Location of system mail spool directory. */
+#undef MAIL_SPOOL_DIR
+
+/* Name of user's mail spool file if stored in user's home directory. */
+#undef MAIL_SPOOL_FILE
+
+/* Define to support the MD5-based password hashing algorithm. */
+#undef MD5_CRYPT
+
+/* Define to use ndbm. */
+#undef NDBM
+
+/* Define to support OPIE one-time password logins. */
+#undef OPIE
+
+/* Package name. */
+#undef PACKAGE
+
+/* Define if pam_strerror() needs two arguments (Linux-PAM 0.59+). */
+#undef PAM_STRERROR_NEEDS_TWO_ARGS
+
+/* Path to passwd program. */
+#undef PASSWD_PROGRAM
+
+/* Define if the compiler understands function prototypes. */
+#undef PROTOTYPES
+
+/* Define if login should support the -r flag for rlogind. */
+#undef RLOGIN
+
+/* Define to the ruserok() "success" return value (0 or 1). */
+#undef RUSEROK
+
+/* Define to support the shadow group file. */
+#undef SHADOWGRP
+
+/* Define to support the shadow password file. */
+#undef SHADOWPWD
+
+/* Define to support S/Key logins. */
+#undef SKEY
+
+/* Define to support /etc/suauth su access control. */
+#undef SU_ACCESS
+
+/* Define to support SecureWare(tm) long passwords. */
+#undef SW_CRYPT
+
+/* Define if you want gdbm for TCFS. */
+#undef TCFS_GDBM_SUPPORT
+
+/* Define to support Pluggable Authentication Modules. */
+#undef USE_PAM
+
+/* Define to use syslog(). */
+#undef USE_SYSLOG
+
+/* Define if you have ut_host in struct utmp. */
+#undef UT_HOST
+
+/* Path for utmp file. */
+#undef _UTMP_FILE
+
+/* Define to ut_name if struct utmp has ut_name (not ut_user). */
+#undef ut_user
+
+/* Version. */
+#undef VERSION
+
+/* Path for wtmp file. */
+#undef _WTMP_FILE
+
diff --git a/current/aclocal.m4 b/current/aclocal.m4
new file mode 100644
index 00000000..7f119fd2
--- /dev/null
+++ b/current/aclocal.m4
@@ -0,0 +1,1027 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+
+# serial 1
+
+AC_DEFUN(AM_C_PROTOTYPES,
+[AC_REQUIRE([AM_PROG_CC_STDC])
+AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([for function prototypes])
+if test "$am_cv_prog_cc_stdc" != no; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(PROTOTYPES,1,[Define if compiler has function prototypes])
+ U= ANSI2KNR=
+else
+ AC_MSG_RESULT(no)
+ U=_ ANSI2KNR=./ansi2knr
+ # Ensure some checks needed by ansi2knr itself.
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS(string.h)
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(AM_PROG_CC_STDC,
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
+dnl a magic option to avoid problems with ANSI preprocessor commands
+dnl like #elif.
+dnl FIXME: can't do this because then AC_AIX won't work due to a
+dnl circular dependency.
+dnl AC_BEFORE([$0], [AC_PROG_CPP])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+], [
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+ AC_MSG_RESULT([none needed])
+else
+ AC_MSG_RESULT($am_cv_prog_cc_stdc)
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 5
+
+AC_DEFUN(AM_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS)
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_CHECK_LIB(intl, gettext,
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)],
+ gt_cv_func_gettext_libintl=no)])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT)
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ if test "$CATOBJEXT" = "NONE"; then
+ AC_MSG_CHECKING([whether catgets can be used])
+ AC_ARG_WITH(catgets,
+ [ --with-catgets use catgets functions if available],
+ nls_cv_use_catgets=$withval, nls_cv_use_catgets=no)
+ AC_MSG_RESULT($nls_cv_use_catgets)
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ dnl No gettext in C library. Try catgets next.
+ AC_CHECK_LIB(i, main)
+ AC_CHECK_FUNC(catgets,
+ [AC_DEFINE(HAVE_CATGETS)
+ INTLOBJS="\$(CATOBJS)"
+ AC_PATH_PROG(GENCAT, gencat, no)dnl
+ if test "$GENCAT" != "no"; then
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, no)
+ if test "$GMSGFMT" = "no"; then
+ AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)
+ fi
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi])
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+ AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+ AC_OUTPUT_COMMANDS(
+ [case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac])
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(AM_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY)
+ fi
+
+ AM_LC_MESSAGES
+ AM_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+ dnl Try to locate is.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile.
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES)
+ fi
+ fi])
+
diff --git a/current/config.guess b/current/config.guess
new file mode 100755
index 00000000..6cb567b8
--- /dev/null
+++ b/current/config.guess
@@ -0,0 +1,1087 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
+# Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+# Please send patches to the Autoconf mailing list <autoconf@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+ if test x"$HOST_CC" != x; then
+ CC_FOR_BUILD="$HOST_CC"
+ else
+ if test x"$CC" != x; then
+ CC_FOR_BUILD="$CC"
+ else
+ CC_FOR_BUILD=cc
+ fi
+ fi
+fi
+
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:NetBSD:*:*)
+ echo powerpc-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ sed 's/^ //' << EOF >$dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ ($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ rm -f $dummy.c $dummy
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo t3e-cray-unicosmk${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ if test -x /usr/bin/objformat; then
+ if test "elf" = "`/usr/bin/objformat`"; then
+ echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+ exit 0
+ fi
+ fi
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ armv*) UNAME_MACHINE=$UNAME_MACHINE ;;
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ ld_help_string=`cd /; ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc)
+ # Determine Lib Version
+ cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.c $dummy
+ echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >$dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >$dummy.c <<EOF
+#ifdef __cplusplus
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:5:7*)
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/current/config.h.in b/current/config.h.in
new file mode 100644
index 00000000..716b7583
--- /dev/null
+++ b/current/config.h.in
@@ -0,0 +1,460 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define to the type of elements in the array set by `getgroups'.
+ Usually this is either `int' or `gid_t'. */
+#undef GETGROUPS_T
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if your struct stat has st_rdev. */
+#undef HAVE_ST_RDEV
+
+/* Define if you have the strftime function. */
+#undef HAVE_STRFTIME
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if utime(file, NULL) sets file's timestamp to the present. */
+#undef HAVE_UTIME_NULL
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef mode_t
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define if the `setpgrp' function takes no argument. */
+#undef SETPGRP_VOID
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm. */
+#undef TM_IN_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define if you do not have <strings.h>, index, bzero, etc.. */
+#undef USG
+
+/* Define to enable password aging. */
+#undef AGING
+
+/* Define if struct passwd has pw_age. */
+#undef ATT_AGE
+
+/* Define if struct passwd has pw_comment. */
+#undef ATT_COMMENT
+
+/* Define if struct passwd has pw_quota. */
+#undef BSD_QUOTA
+
+/* Define if you have secure RPC. */
+#undef DES_RPC
+
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Path for faillog file. */
+#undef FAILLOG_FILE
+
+/* Define to libshadow_getpass to use our own version of getpass(). */
+#undef getpass
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Defined if you have libcrack. */
+#undef HAVE_LIBCRACK
+
+/* Defined if you have the ts&szs cracklib. */
+#undef HAVE_LIBCRACK_HIST
+
+/* Defined if it includes *Pw functions. */
+#undef HAVE_LIBCRACK_PW
+
+/* Defined if you have libcrypt. */
+#undef HAVE_LIBCRYPT
+
+/* Define if struct lastlog has ll_host */
+#undef HAVE_LL_HOST
+
+/* Working shadow group support in libc? */
+#undef HAVE_SHADOWGRP
+
+/* Define to 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define to support TCFS. */
+#undef HAVE_TCFS
+
+/* Path for lastlog file. */
+#undef LASTLOG_FILE
+
+/* Define to support /etc/login.access login access control. */
+#undef LOGIN_ACCESS
+
+/* Location of system mail spool directory. */
+#undef MAIL_SPOOL_DIR
+
+/* Name of user's mail spool file if stored in user's home directory. */
+#undef MAIL_SPOOL_FILE
+
+/* Define to support the MD5-based password hashing algorithm. */
+#undef MD5_CRYPT
+
+/* Define to support OPIE one-time password logins. */
+#undef OPIE
+
+/* Define if pam_strerror() needs two arguments (Linux-PAM 0.59+). */
+#undef PAM_STRERROR_NEEDS_TWO_ARGS
+
+/* Path to passwd program. */
+#undef PASSWD_PROGRAM
+
+/* Define if login should support the -r flag for rlogind. */
+#undef RLOGIN
+
+/* Define to the ruserok() "success" return value (0 or 1). */
+#undef RUSEROK
+
+/* Define to support the shadow group file. */
+#undef SHADOWGRP
+
+/* Define to support the shadow password file. */
+#undef SHADOWPWD
+
+/* Define to support S/Key logins. */
+#undef SKEY
+
+/* Define to support /etc/suauth su access control. */
+#undef SU_ACCESS
+
+/* Define if you want gdbm for TCFS. */
+#undef TCFS_GDBM_SUPPORT
+
+/* Define to support Pluggable Authentication Modules. */
+#undef USE_PAM
+
+/* Define to use syslog(). */
+#undef USE_SYSLOG
+
+/* Define if you have ut_host in struct utmp. */
+#undef UT_HOST
+
+/* Path for utmp file. */
+#undef _UTMP_FILE
+
+/* Define to ut_name if struct utmp has ut_name (not ut_user). */
+#undef ut_user
+
+/* Path for wtmp file. */
+#undef _WTMP_FILE
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the a64l function. */
+#undef HAVE_A64L
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the fchmod function. */
+#undef HAVE_FCHMOD
+
+/* Define if you have the fchown function. */
+#undef HAVE_FCHOWN
+
+/* Define if you have the fsync function. */
+#undef HAVE_FSYNC
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getgroups function. */
+#undef HAVE_GETGROUPS
+
+/* Define if you have the gethostname function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getspnam function. */
+#undef HAVE_GETSPNAM
+
+/* Define if you have the gettimeofday function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the getusershell function. */
+#undef HAVE_GETUSERSHELL
+
+/* Define if you have the getutent function. */
+#undef HAVE_GETUTENT
+
+/* Define if you have the initgroups function. */
+#undef HAVE_INITGROUPS
+
+/* Define if you have the lchown function. */
+#undef HAVE_LCHOWN
+
+/* Define if you have the lckpwdf function. */
+#undef HAVE_LCKPWDF
+
+/* Define if you have the lstat function. */
+#undef HAVE_LSTAT
+
+/* Define if you have the memcpy function. */
+#undef HAVE_MEMCPY
+
+/* Define if you have the memset function. */
+#undef HAVE_MEMSET
+
+/* Define if you have the mkdir function. */
+#undef HAVE_MKDIR
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the putgrent function. */
+#undef HAVE_PUTGRENT
+
+/* Define if you have the putpwent function. */
+#undef HAVE_PUTPWENT
+
+/* Define if you have the putspent function. */
+#undef HAVE_PUTSPENT
+
+/* Define if you have the rename function. */
+#undef HAVE_RENAME
+
+/* Define if you have the rmdir function. */
+#undef HAVE_RMDIR
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setgroups function. */
+#undef HAVE_SETGROUPS
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the sgetgrent function. */
+#undef HAVE_SGETGRENT
+
+/* Define if you have the sgetpwent function. */
+#undef HAVE_SGETPWENT
+
+/* Define if you have the sgetspent function. */
+#undef HAVE_SGETSPENT
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the snprintf function. */
+#undef HAVE_SNPRINTF
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the updwtmp function. */
+#undef HAVE_UPDWTMP
+
+/* Define if you have the updwtmpx function. */
+#undef HAVE_UPDWTMPX
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <gshadow.h> header file. */
+#undef HAVE_GSHADOW_H
+
+/* Define if you have the <lastlog.h> header file. */
+#undef HAVE_LASTLOG_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define if you have the <rpc/key_prot.h> header file. */
+#undef HAVE_RPC_KEY_PROT_H
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the <shadow.h> header file. */
+#undef HAVE_SHADOW_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <ulimit.h> header file. */
+#undef HAVE_ULIMIT_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <usersec.h> header file. */
+#undef HAVE_USERSEC_H
+
+/* Define if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define if you have the <utmp.h> header file. */
+#undef HAVE_UTMP_H
+
+/* Define if you have the <utmpx.h> header file. */
+#undef HAVE_UTMPX_H
+
+/* Define if you have the i library (-li). */
+#undef HAVE_LIBI
+
+/* Define if you have the inet library (-linet). */
+#undef HAVE_LIBINET
+
+/* Define if you have the nsl library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the socket library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if compiler has function prototypes */
+#undef PROTOTYPES
+
diff --git a/current/config.sub b/current/config.sub
new file mode 100755
index 00000000..2436b453
--- /dev/null
+++ b/current/config.sub
@@ -0,0 +1,1215 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=vxworks
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
+ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+ | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+ | mips64vr5000 | miprs64vr5000el \
+ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+ | thumb | d10v)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+ | xmp-* | ymp-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+ | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+ | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-* | armv*-* | t3e-* \
+ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+ | thumb-* | v850-* | d30v-* | tic30-* | c30-* )
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ i386-go32 | go32)
+ basic_machine=i386-unknown
+ os=-go32
+ ;;
+ i386-mingw32 | mingw32)
+ basic_machine=i386-unknown
+ os=-mingw32
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | *MiNT)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos)
+ basic_machine=i386-unknown
+ os=-msdos
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-corel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=t3e-cray
+ os=-unicos
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc | sparcv9)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -*MiNT)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-corel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -*MiNT)
+ vendor=atari
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/current/configure b/current/configure
new file mode 100755
index 00000000..8de554bb
--- /dev/null
+++ b/current/configure
@@ -0,0 +1,6803 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --enable-desrpc try to use secure RPC in login (default if found)"
+ac_help="$ac_help
+ --enable-shadowgrp enable shadow group support [default=yes]"
+ac_help="$ac_help
+ --with-libcrack try to use libcrack (default if found)"
+ac_help="$ac_help
+ --with-libcrypt try to use libcrypt (default if found)"
+ac_help="$ac_help
+ --with-libopie use libopie for OPIE support"
+ac_help="$ac_help
+ --with-libpam use libpam for PAM support"
+ac_help="$ac_help
+ --with-libskey use libskey for S/Key support"
+ac_help="$ac_help
+ --with-libtcfs use libtcfs for TCFS support"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --with-catgets use catgets functions if available"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=lib/dialchk.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:588: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:641: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:698: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=shadow
+
+VERSION=20000902
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:744: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:757: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:770: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:783: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:796: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+test "$prefix" = "NONE" && prefix="/usr"
+test "$prefix" = "/usr" && exec_prefix=""
+test "$CFLAGS" = "" && CFLAGS="-O2 -Wall"
+test "$LDFLAGS" = "" && LDFLAGS="-s"
+
+ALL_LINGUAS="el fr pl sv"
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:823: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:853: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:904: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:936: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 947 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:952: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:978: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:983: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:992: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1011: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:1043: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1064: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1089: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:1123: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ cat > conftest.$ac_ext <<EOF
+#line 1139 "configure"
+#include "confdefs.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+
+int main() {
+
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+
+; return 0; }
+EOF
+if { (eval echo configure:1176: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_prog_cc_stdc="$ac_arg"; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CC="$ac_save_CC"
+
+fi
+
+if test -z "$am_cv_prog_cc_stdc"; then
+ echo "$ac_t""none needed" 1>&6
+else
+ echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1200: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1215 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1232 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1249 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1255: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+
+echo $ac_n "checking for function prototypes""... $ac_c" 1>&6
+echo "configure:1282: checking for function prototypes" >&5
+if test "$am_cv_prog_cc_stdc" != no; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define PROTOTYPES 1
+EOF
+
+ U= ANSI2KNR=
+else
+ echo "$ac_t""no" 1>&6
+ U=_ ANSI2KNR=./ansi2knr
+ # Ensure some checks needed by ansi2knr itself.
+ echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1295: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1300 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1308: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1325 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1343 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1364 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+ for ac_hdr in string.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1402: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1407 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1412: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1516: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1537: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1557: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1596: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1620: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1623: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1659: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1675: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1735 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1736: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1757: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1762 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:1877: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1882 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:1890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:1915: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1923 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1934: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:1956: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1964 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1998: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2003 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2011: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2028 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2046 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2067 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:2102: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2107 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:2123: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h limits.h unistd.h sys/time.h utmp.h utmpx.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2147: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2152 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in termios.h termio.h sgtty.h sys/ioctl.h syslog.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2187: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2192 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in paths.h usersec.h utime.h ulimit.h sys/resource.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2227: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2232 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2237: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in gshadow.h shadow.h lastlog.h rpc/key_prot.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2267: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2272 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2277: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2305: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2310 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:2380: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2385 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "uid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_uid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2414: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2419 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:2447: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2452 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for mode_t""... $ac_c" 1>&6
+echo "configure:2480: checking for mode_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2485 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_mode_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_mode_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_mode_t" 1>&6
+if test $ac_cv_type_mode_t = no; then
+ cat >> confdefs.h <<\EOF
+#define mode_t int
+EOF
+
+fi
+
+echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
+echo "configure:2513: checking for st_rdev in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2518 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_rdev;
+; return 0; }
+EOF
+if { (eval echo configure:2526: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_st_rdev=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_st_rdev=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_rdev" 1>&6
+if test $ac_cv_struct_st_rdev = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ST_RDEV 1
+EOF
+
+fi
+
+echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
+echo "configure:2547: checking whether stat file-mode macros are broken" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2552 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(S_ISBLK) && defined(S_IFDIR)
+# if S_ISBLK (S_IFDIR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISBLK) && defined(S_IFCHR)
+# if S_ISBLK (S_IFCHR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISLNK) && defined(S_IFREG)
+# if S_ISLNK (S_IFREG)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISSOCK) && defined(S_IFREG)
+# if S_ISSOCK (S_IFREG)
+You lose.
+# endif
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "You lose" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_header_stat_broken=yes
+else
+ rm -rf conftest*
+ ac_cv_header_stat_broken=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_header_stat_broken" 1>&6
+if test $ac_cv_header_stat_broken = yes; then
+ cat >> confdefs.h <<\EOF
+#define STAT_MACROS_BROKEN 1
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:2603: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2608 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:2617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:2638: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2643 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:2651: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for pw_age in struct passwd""... $ac_c" 1>&6
+echo "configure:2673: checking for pw_age in struct passwd" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_passwd_pw_age'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2678 "configure"
+#include "confdefs.h"
+#include <pwd.h>
+int main() {
+ struct passwd pw; pw.pw_age = "";
+; return 0; }
+EOF
+if { (eval echo configure:2685: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_passwd_pw_age=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_passwd_pw_age=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_passwd_pw_age" 1>&6
+
+if test "$ac_cv_struct_passwd_pw_age" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ATT_AGE 1
+EOF
+
+fi
+
+echo $ac_n "checking for pw_comment in struct passwd""... $ac_c" 1>&6
+echo "configure:2707: checking for pw_comment in struct passwd" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_passwd_pw_comment'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2712 "configure"
+#include "confdefs.h"
+#include <pwd.h>
+int main() {
+ struct passwd pw; pw.pw_comment = "";
+; return 0; }
+EOF
+if { (eval echo configure:2719: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_passwd_pw_comment=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_passwd_pw_comment=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_passwd_pw_comment" 1>&6
+
+if test "$ac_cv_struct_passwd_pw_comment" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ATT_COMMENT 1
+EOF
+
+fi
+
+echo $ac_n "checking for pw_quota in struct passwd""... $ac_c" 1>&6
+echo "configure:2741: checking for pw_quota in struct passwd" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_passwd_pw_quota'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2746 "configure"
+#include "confdefs.h"
+#include <pwd.h>
+int main() {
+ struct passwd pw; pw.pw_quota = 0;
+; return 0; }
+EOF
+if { (eval echo configure:2753: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_passwd_pw_quota=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_passwd_pw_quota=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_passwd_pw_quota" 1>&6
+
+if test "$ac_cv_struct_passwd_pw_quota" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define BSD_QUOTA 1
+EOF
+
+fi
+
+if test "$ac_cv_header_utmp_h" = "yes"; then
+ echo $ac_n "checking for ut_host in struct utmp""... $ac_c" 1>&6
+echo "configure:2776: checking for ut_host in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_utmp_ut_host'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2781 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+ struct utmp ut; char *cp = ut.ut_host;
+; return 0; }
+EOF
+if { (eval echo configure:2788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_utmp_ut_host=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_utmp_ut_host=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_utmp_ut_host" 1>&6
+
+ if test "$ac_cv_struct_utmp_ut_host" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define UT_HOST 1
+EOF
+
+ fi
+
+ echo $ac_n "checking for ut_user in struct utmp""... $ac_c" 1>&6
+echo "configure:2810: checking for ut_user in struct utmp" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_utmp_ut_user'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2815 "configure"
+#include "confdefs.h"
+#include <utmp.h>
+int main() {
+ struct utmp ut; char *cp = ut.ut_user;
+; return 0; }
+EOF
+if { (eval echo configure:2822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_utmp_ut_user=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_utmp_ut_user=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_utmp_ut_user" 1>&6
+
+ if test "$ac_cv_struct_utmp_ut_user" = "no"; then
+ cat >> confdefs.h <<\EOF
+#define ut_user ut_name
+EOF
+
+ fi
+fi
+
+if test "$ac_cv_header_lastlog_h" = "yes"; then
+ echo $ac_n "checking for ll_host in struct lastlog""... $ac_c" 1>&6
+echo "configure:2846: checking for ll_host in struct lastlog" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_lastlog_ll_host'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2851 "configure"
+#include "confdefs.h"
+#include <lastlog.h>
+int main() {
+ struct lastlog ll; char *cp = ll.ll_host;
+; return 0; }
+EOF
+if { (eval echo configure:2858: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_lastlog_ll_host=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_lastlog_ll_host=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_lastlog_ll_host" 1>&6
+
+ if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LL_HOST 1
+EOF
+
+ fi
+fi
+
+echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
+echo "configure:2881: checking type of array argument to getgroups" >&5
+if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_type_getgroups=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2889 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Rendell for this test. */
+#include <sys/types.h>
+#define NGID 256
+#undef MAX
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+main()
+{
+ gid_t gidset[NGID];
+ int i, n;
+ union { gid_t gval; long lval; } val;
+
+ val.lval = -1;
+ for (i = 0; i < NGID; i++)
+ gidset[i] = val.gval;
+ n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
+ gidset);
+ /* Exit non-zero if getgroups seems to require an array of ints. This
+ happens when gid_t is short but getgroups modifies an array of ints. */
+ exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
+}
+
+EOF
+if { (eval echo configure:2914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_type_getgroups=gid_t
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_type_getgroups=int
+fi
+rm -fr conftest*
+fi
+
+if test $ac_cv_type_getgroups = cross; then
+ cat > conftest.$ac_ext <<EOF
+#line 2928 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_getgroups=gid_t
+else
+ rm -rf conftest*
+ ac_cv_type_getgroups=int
+fi
+rm -f conftest*
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_type_getgroups" 1>&6
+cat >> confdefs.h <<EOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+EOF
+
+
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:2953: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 2959 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 2977 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:2999: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3004 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:3021: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking whether utime accepts a null argument""... $ac_c" 1>&6
+echo "configure:3040: checking whether utime accepts a null argument" >&5
+if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata; > conftestdata
+# Sequent interprets utime(file, 0) to mean use start of epoch. Wrong.
+if test "$cross_compiling" = yes; then
+ ac_cv_func_utime_null=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3050 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+main() {
+struct stat s, t;
+exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0
+&& stat("conftestdata", &t) == 0 && t.st_mtime >= s.st_mtime
+&& t.st_mtime - s.st_mtime < 120));
+}
+EOF
+if { (eval echo configure:3061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_utime_null=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_utime_null=no
+fi
+rm -fr conftest*
+fi
+
+rm -f core core.* *.core
+fi
+
+echo "$ac_t""$ac_cv_func_utime_null" 1>&6
+if test $ac_cv_func_utime_null = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_UTIME_NULL 1
+EOF
+
+fi
+
+echo $ac_n "checking for strftime""... $ac_c" 1>&6
+echo "configure:3085: checking for strftime" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3090 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strftime(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strftime) || defined (__stub___strftime)
+choke me
+#else
+strftime();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+# strftime is in -lintl on SCO UNIX.
+echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
+echo "configure:3135: checking for strftime in -lintl" >&5
+ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3143 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+strftime()
+; return 0; }
+EOF
+if { (eval echo configure:3154: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+LIBS="-lintl $LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in a64l fchmod fchown fsync getgroups gethostname getspnam
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3183: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3188 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in gettimeofday getusershell getutent initgroups lchown lckpwdf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3238: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3243 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in lstat memcpy memset setgroups sigaction strchr updwtmp updwtmpx
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3293: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3298 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_func in mkdir putgrent putpwent putspent rename rmdir
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3349: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3354 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+for ac_func in sgetgrent sgetpwent sgetspent
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3406: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3411 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+for ac_func in snprintf strcasecmp strdup strerror strstr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3463: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3468 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+
+echo $ac_n "checking for setpgrp""... $ac_c" 1>&6
+echo "configure:3519: checking for setpgrp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setpgrp'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3524 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char setpgrp(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char setpgrp();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_setpgrp) || defined (__stub___setpgrp)
+choke me
+#else
+setpgrp();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_setpgrp=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_setpgrp=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'setpgrp`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
+echo "configure:3567: checking whether setpgrp takes no argument" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3575 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/*
+ * If this system has a BSD-style setpgrp, which takes arguments, exit
+ * successfully.
+ */
+main()
+{
+ if (setpgrp(1,1) == -1)
+ exit(0);
+ else
+ exit(1);
+}
+
+EOF
+if { (eval echo configure:3595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_setpgrp_void=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_setpgrp_void=yes
+fi
+rm -fr conftest*
+fi
+
+
+fi
+
+echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6
+if test $ac_cv_func_setpgrp_void = yes; then
+ cat >> confdefs.h <<\EOF
+#define SETPGRP_VOID 1
+EOF
+
+fi
+
+
+if test "$ac_cv_header_shadow_h" = "yes"; then
+echo $ac_n "checking for working shadow group support""... $ac_c" 1>&6
+echo "configure:3621: checking for working shadow group support" >&5
+if eval "test \"`echo '$''{'ac_cv_libc_shadowgrp'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_libc_shadowgrp=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3629 "configure"
+#include "confdefs.h"
+
+#include <shadow.h>
+main()
+{
+ struct sgrp *sg = sgetsgent("test:x::");
+ /* NYS libc on Red Hat 3.0.3 has broken shadow group support */
+ return !sg || !sg->sg_adm || !sg->sg_mem;
+}
+
+EOF
+if { (eval echo configure:3641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_libc_shadowgrp=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_libc_shadowgrp=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_libc_shadowgrp" 1>&6
+
+if test "$ac_cv_libc_shadowgrp" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SHADOWGRP 1
+EOF
+
+fi
+fi
+
+echo $ac_n "checking location of shared mail directory""... $ac_c" 1>&6
+echo "configure:3666: checking location of shared mail directory" >&5
+for maildir in /var/spool/mail /var/mail /usr/spool/mail /usr/mail NONE; do
+ if test "$maildir" = "NONE"; then
+ echo "$ac_t""None" 1>&6
+ elif test -d $maildir; then
+ cat >> confdefs.h <<EOF
+#define MAIL_SPOOL_DIR "$maildir"
+EOF
+
+ echo "$ac_t""$maildir" 1>&6
+ break
+ fi
+done
+
+echo $ac_n "checking location of user mail file""... $ac_c" 1>&6
+echo "configure:3681: checking location of user mail file" >&5
+for mailfile in Mailbox mailbox Mail mail .mail NONE; do
+ if test "$mailfile" = "NONE"; then
+ echo "$ac_t""None" 1>&6
+ elif test -f $HOME/$mailfile; then
+ cat >> confdefs.h <<EOF
+#define MAIL_SPOOL_FILE "$mailfile"
+EOF
+
+ echo "$ac_t""$mailfile" 1>&6
+ break
+ fi
+done
+
+echo $ac_n "checking location of utmp""... $ac_c" 1>&6
+echo "configure:3696: checking location of utmp" >&5
+for utmpdir in /var/run /var/adm /usr/adm /etc NONE; do
+ if test "$utmpdir" = "NONE"; then
+ echo "configure: warning: utmp file not found" 1>&2
+ elif test -f $utmpdir/utmp; then
+ cat >> confdefs.h <<EOF
+#define _UTMP_FILE "$utmpdir/utmp"
+EOF
+
+ echo "$ac_t""$utmpdir" 1>&6
+ break
+ fi
+done
+
+echo $ac_n "checking location of faillog/lastlog/wtmp""... $ac_c" 1>&6
+echo "configure:3711: checking location of faillog/lastlog/wtmp" >&5
+for logdir in /var/log /var/adm /usr/adm /etc; do
+ if test -d $logdir; then
+ cat >> confdefs.h <<EOF
+#define _WTMP_FILE "$logdir/wtmp"
+EOF
+
+ cat >> confdefs.h <<EOF
+#define LASTLOG_FILE "$logdir/lastlog"
+EOF
+
+ cat >> confdefs.h <<EOF
+#define FAILLOG_FILE "$logdir/faillog"
+EOF
+
+ echo "$ac_t""$logdir" 1>&6
+ break
+ fi
+done
+
+echo $ac_n "checking location of the passwd program""... $ac_c" 1>&6
+echo "configure:3732: checking location of the passwd program" >&5
+if test -f /usr/bin/passwd; then
+ passwd_dir=/usr/bin
+else
+ passwd_dir=/bin
+fi
+cat >> confdefs.h <<EOF
+#define PASSWD_PROGRAM "$passwd_dir/passwd"
+EOF
+
+echo "$ac_t""$passwd_dir" 1>&6
+
+cat >> confdefs.h <<\EOF
+#define SHADOWPWD 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define USG 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define AGING 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define USE_SYSLOG 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define RLOGIN 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define RUSEROK 0
+EOF
+
+cat >> confdefs.h <<\EOF
+#define LOGIN_ACCESS 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define SU_ACCESS 1
+EOF
+
+
+cat >> confdefs.h <<\EOF
+#define getpass libshadow_getpass
+EOF
+
+
+# Check whether --enable-desrpc or --disable-desrpc was given.
+if test "${enable_desrpc+set}" = set; then
+ enableval="$enable_desrpc"
+ :
+fi
+
+# Check whether --enable-shadowgrp or --disable-shadowgrp was given.
+if test "${enable_shadowgrp+set}" = set; then
+ enableval="$enable_shadowgrp"
+ :
+fi
+
+
+# Check whether --with-libcrack or --without-libcrack was given.
+if test "${with_libcrack+set}" = set; then
+ withval="$with_libcrack"
+ :
+fi
+
+# Check whether --with-libcrypt or --without-libcrypt was given.
+if test "${with_libcrypt+set}" = set; then
+ withval="$with_libcrypt"
+ :
+fi
+
+# Check whether --with-libopie or --without-libopie was given.
+if test "${with_libopie+set}" = set; then
+ withval="$with_libopie"
+ :
+fi
+
+# Check whether --with-libpam or --without-libpam was given.
+if test "${with_libpam+set}" = set; then
+ withval="$with_libpam"
+ :
+fi
+
+# Check whether --with-libskey or --without-libskey was given.
+if test "${with_libskey+set}" = set; then
+ withval="$with_libskey"
+ :
+fi
+
+# Check whether --with-libtcfs or --without-libtcfs was given.
+if test "${with_libtcfs+set}" = set; then
+ withval="$with_libtcfs"
+ :
+fi
+
+
+
+echo $ac_n "checking for inet_ntoa""... $ac_c" 1>&6
+echo "configure:3834: checking for inet_ntoa" >&5
+if eval "test \"`echo '$''{'ac_cv_func_inet_ntoa'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3839 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char inet_ntoa(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_ntoa();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_inet_ntoa) || defined (__stub___inet_ntoa)
+choke me
+#else
+inet_ntoa();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3862: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_inet_ntoa=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_inet_ntoa=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'inet_ntoa`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for inet_ntoa in -linet""... $ac_c" 1>&6
+echo "configure:3880: checking for inet_ntoa in -linet" >&5
+ac_lib_var=`echo inet'_'inet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3888 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_ntoa();
+
+int main() {
+inet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:3899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/^a-zA-Z0-9_/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-linet $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for socket""... $ac_c" 1>&6
+echo "configure:3929: checking for socket" >&5
+if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3934 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char socket(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_socket) || defined (__stub___socket)
+choke me
+#else
+socket();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_socket=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_socket=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
+echo "configure:3975: checking for socket in -lsocket" >&5
+ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsocket $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3983 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:3994: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lsocket $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:4024: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4029 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostbyname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:4070: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4078 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:4089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lnsl $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+
+if test "$enable_desrpc" != "no" -a "$ac_cv_header_rpc_key_prot_h" = "yes" ; then
+ echo $ac_n "checking for getsecretkey""... $ac_c" 1>&6
+echo "configure:4122: checking for getsecretkey" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getsecretkey'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4127 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getsecretkey(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getsecretkey();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getsecretkey) || defined (__stub___getsecretkey)
+choke me
+#else
+getsecretkey();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getsecretkey=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getsecretkey=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getsecretkey`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define DES_RPC 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for getsecretkey in -lrpcsvc""... $ac_c" 1>&6
+echo "configure:4171: checking for getsecretkey in -lrpcsvc" >&5
+ac_lib_var=`echo rpcsvc'_'getsecretkey | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lrpcsvc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4179 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getsecretkey();
+
+int main() {
+getsecretkey()
+; return 0; }
+EOF
+if { (eval echo configure:4190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define DES_RPC 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+fi
+
+if test "$enable_shadowgrp" != "no"; then
+ cat >> confdefs.h <<\EOF
+#define SHADOWGRP 1
+EOF
+
+fi
+
+
+if test "$with_libcrypt" != "no"; then
+ echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
+echo "configure:4227: checking for crypt in -lcrypt" >&5
+ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrypt $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4235 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char crypt();
+
+int main() {
+crypt()
+; return 0; }
+EOF
+if { (eval echo configure:4246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBCRYPT 1
+EOF
+ LIBCRYPT=-lcrypt
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+if test "$enable_md5crypt" = "yes"; then
+ LIBOBJS="$LIBOBJS md5.o md5crypt.o"
+ cat >> confdefs.h <<\EOF
+#define MD5_CRYPT 1
+EOF
+
+fi
+
+
+if test "$with_libcrack" != "no"; then
+ echo "checking cracklib flavour, don't be surprised by the results"
+ echo $ac_n "checking for FascistCheck in -lcrack""... $ac_c" 1>&6
+echo "configure:4283: checking for FascistCheck in -lcrack" >&5
+ac_lib_var=`echo crack'_'FascistCheck | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrack $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4291 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char FascistCheck();
+
+int main() {
+FascistCheck()
+; return 0; }
+EOF
+if { (eval echo configure:4302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBCRACK 1
+EOF
+ LIBCRACK=-lcrack
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for FascistHistory in -lcrack""... $ac_c" 1>&6
+echo "configure:4326: checking for FascistHistory in -lcrack" >&5
+ac_lib_var=`echo crack'_'FascistHistory | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrack $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4334 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char FascistHistory();
+
+int main() {
+FascistHistory()
+; return 0; }
+EOF
+if { (eval echo configure:4345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBCRACK_HIST 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for FascistHistoryPw in -lcrack""... $ac_c" 1>&6
+echo "configure:4369: checking for FascistHistoryPw in -lcrack" >&5
+ac_lib_var=`echo crack'_'FascistHistoryPw | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrack $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4377 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char FascistHistoryPw();
+
+int main() {
+FascistHistoryPw()
+; return 0; }
+EOF
+if { (eval echo configure:4388: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBCRACK_PW 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+
+if test "$with_libskey" = "yes"; then
+ echo $ac_n "checking for MD5Init in -lmd""... $ac_c" 1>&6
+echo "configure:4417: checking for MD5Init in -lmd" >&5
+ac_lib_var=`echo md'_'MD5Init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lmd $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4425 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char MD5Init();
+
+int main() {
+MD5Init()
+; return 0; }
+EOF
+if { (eval echo configure:4436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBMD=-lmd
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for skeychallenge in -lskey""... $ac_c" 1>&6
+echo "configure:4457: checking for skeychallenge in -lskey" >&5
+ac_lib_var=`echo skey'_'skeychallenge | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lskey $LIBMD $LIBCRYPT $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4465 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char skeychallenge();
+
+int main() {
+skeychallenge()
+; return 0; }
+EOF
+if { (eval echo configure:4476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SKEY 1
+EOF
+ LIBSKEY=-lskey
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+elif test "$with_libopie" = "yes"; then
+ echo $ac_n "checking for opiechallenge in -lopie""... $ac_c" 1>&6
+echo "configure:4501: checking for opiechallenge in -lopie" >&5
+ac_lib_var=`echo opie'_'opiechallenge | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lopie $LIBCRYPT $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4509 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opiechallenge();
+
+int main() {
+opiechallenge()
+; return 0; }
+EOF
+if { (eval echo configure:4520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define OPIE 1
+EOF
+ LIBSKEY=-lopie
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+if test "$with_libtcfs" = "yes"; then
+ echo $ac_n "checking for tcfs_encrypt_key in -ltcfs""... $ac_c" 1>&6
+echo "configure:4548: checking for tcfs_encrypt_key in -ltcfs" >&5
+ac_lib_var=`echo tcfs'_'tcfs_encrypt_key | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ltcfs -lgdbm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4556 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tcfs_encrypt_key();
+
+int main() {
+tcfs_encrypt_key()
+; return 0; }
+EOF
+if { (eval echo configure:4567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_TCFS 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define TCFS_GDBM_SUPPORT 1
+EOF
+ LIBTCFS="-ltcfs -lgdbm"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+if test "$with_libpam" = "yes"; then
+ LIBPAM="-lpam -lpam_misc -ldl"
+ cat >> confdefs.h <<\EOF
+#define USE_PAM 1
+EOF
+
+ echo $ac_n "checking whether pam_strerror needs two arguments""... $ac_c" 1>&6
+echo "configure:4603: checking whether pam_strerror needs two arguments" >&5
+if eval "test \"`echo '$''{'ac_cv_pam_strerror_needs_two_args'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4608 "configure"
+#include "confdefs.h"
+#include <security/pam_appl.h>
+int main() {
+ pam_handle_t *pamh; pam_strerror(pamh, PAM_SUCCESS);
+; return 0; }
+EOF
+if { (eval echo configure:4615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_pam_strerror_needs_two_args=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_pam_strerror_needs_two_args=no
+
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_pam_strerror_needs_two_args" 1>&6
+ if test "$ac_cv_pam_strerror_needs_two_args" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define PAM_STRERROR_NEEDS_TWO_ARGS 1
+EOF
+
+ fi
+fi
+
+LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.o/.lo/g'`
+
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:4642: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 4649 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:4656: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:4682: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4687 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:4717: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4722 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:4729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:4750: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4755 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:4783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:4815: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4820 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4845: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4850 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:4900: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4908 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:4927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4952: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4957 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4962: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4991: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4996 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:5044: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5052 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:5192: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5220: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5225 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5230: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5260: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5265 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5317: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5322 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:5379: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5384 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:5391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:5412: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:5432: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:5451: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5456 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:5478: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5483 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:5490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:5506: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5514 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:5525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:5541: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
+echo "configure:5546: checking for gettext in -lintl" >&5
+ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5554 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gettext();
+
+int main() {
+gettext()
+; return 0; }
+EOF
+if { (eval echo configure:5565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "$ac_t""no" 1>&6
+gt_cv_func_gettext_libintl=no
+fi
+
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5604: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5638: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5643 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5693: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5729: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 5761 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:5769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
+echo "configure:5792: checking whether catgets can be used" >&5
+ # Check whether --with-catgets or --without-catgets was given.
+if test "${with_catgets+set}" = set; then
+ withval="$with_catgets"
+ nls_cv_use_catgets=$withval
+else
+ nls_cv_use_catgets=no
+fi
+
+ echo "$ac_t""$nls_cv_use_catgets" 1>&6
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ echo $ac_n "checking for main in -li""... $ac_c" 1>&6
+echo "configure:5805: checking for main in -li" >&5
+ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-li $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5813 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:5820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo i | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-li $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for catgets""... $ac_c" 1>&6
+echo "configure:5848: checking for catgets" >&5
+if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5853 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char catgets(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char catgets();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_catgets) || defined (__stub___catgets)
+choke me
+#else
+catgets();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_catgets=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_catgets=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'catgets`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_CATGETS 1
+EOF
+
+ INTLOBJS="\$(CATOBJS)"
+ # Extract the first word of "gencat", so it can be a program name with args.
+set dummy gencat; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5898: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GENCAT" in
+ /*)
+ ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GENCAT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no"
+ ;;
+esac
+fi
+GENCAT="$ac_cv_path_GENCAT"
+if test -n "$GENCAT"; then
+ echo "$ac_t""$GENCAT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$GENCAT" != "no"; then
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5934: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "$GMSGFMT" = "no"; then
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5971: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6006: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6064: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6098: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6134: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:6227: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:6255: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6260 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6265: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+
+
+ l=
+
+
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "libmisc/Makefile man/Makefile man/pl/Makefile
+ lib/Makefile src/Makefile Makefile
+ contrib/Makefile debian/Makefile doc/Makefile etc/Makefile
+ intl/Makefile intl/po2tbl.sed po/Makefile.in
+ etc/pam.d/Makefile old/Makefile
+ redhat/Makefile redhat/shadow-utils.spec config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@YACC@%$YACC%g
+s%@CPP@%$CPP%g
+s%@U@%$U%g
+s%@ANSI2KNR@%$ANSI2KNR%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@RANLIB@%$RANLIB%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@LIBCRYPT@%$LIBCRYPT%g
+s%@LIBCRACK@%$LIBCRACK%g
+s%@LIBSKEY@%$LIBSKEY%g
+s%@LIBMD@%$LIBMD%g
+s%@LIBTCFS@%$LIBTCFS%g
+s%@LIBPAM@%$LIBPAM%g
+s%@LTLIBOBJS@%$LTLIBOBJS%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@GENCAT@%$GENCAT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"libmisc/Makefile man/Makefile man/pl/Makefile
+ lib/Makefile src/Makefile Makefile
+ contrib/Makefile debian/Makefile doc/Makefile etc/Makefile
+ intl/Makefile intl/po2tbl.sed po/Makefile.in
+ etc/pam.d/Makefile old/Makefile
+ redhat/Makefile redhat/shadow-utils.spec"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+ac_sources="$nls_cv_header_libgt"
+ac_dests="$nls_cv_header_intl"
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+srcdir=$ac_given_srcdir
+while test -n "$ac_sources"; do
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+ set $ac_sources; ac_source=$1; shift; ac_sources=$*
+
+ echo "linking $srcdir/$ac_source to $ac_dest"
+
+ if test ! -r $srcdir/$ac_source; then
+ { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
+ fi
+ rm -f $ac_dest
+
+ # Make relative symlinks.
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
+ # The dest file is in a subdirectory.
+ test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
+ ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dest_dir_suffix.
+ ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dest_dir_suffix= ac_dots=
+ fi
+
+ case "$srcdir" in
+ [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
+ *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
+ esac
+
+ # Make a symlink if possible; otherwise try a hard link.
+ if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+ ln $srcdir/$ac_source $ac_dest; then :
+ else
+ { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
+ fi
+done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac
+echo timestamp > stamp-h
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
diff --git a/current/configure.in b/current/configure.in
new file mode 100644
index 00000000..1af42d8f
--- /dev/null
+++ b/current/configure.in
@@ -0,0 +1,311 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(lib/dialchk.c)
+AM_INIT_AUTOMAKE(shadow, 20000902)
+AM_CONFIG_HEADER(config.h)
+
+dnl Some hacks...
+test "$prefix" = "NONE" && prefix="/usr"
+test "$prefix" = "/usr" && exec_prefix=""
+test "$CFLAGS" = "" && CFLAGS="-O2 -Wall"
+test "$LDFLAGS" = "" && LDFLAGS="-s"
+
+ALL_LINGUAS="el fr pl sv"
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_ISC_POSIX
+dnl AC_PROG_INSTALL
+AC_PROG_LN_S
+dnl AC_PROG_MAKE_SET
+AC_PROG_YACC
+dnl AC_ARG_PROGRAM
+AM_C_PROTOTYPES
+AM_PROG_LIBTOOL
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h limits.h unistd.h sys/time.h utmp.h utmpx.h)
+AC_CHECK_HEADERS(termios.h termio.h sgtty.h sys/ioctl.h syslog.h)
+AC_CHECK_HEADERS(paths.h usersec.h utime.h ulimit.h sys/resource.h)
+AC_CHECK_HEADERS(gshadow.h shadow.h lastlog.h rpc/key_prot.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_UID_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_MODE_T
+AC_STRUCT_ST_RDEV
+AC_HEADER_STAT
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+AC_CACHE_CHECK(for pw_age in struct passwd,
+ac_cv_struct_passwd_pw_age, AC_TRY_COMPILE([#include <pwd.h>],
+[ struct passwd pw; pw.pw_age = ""; ],
+ac_cv_struct_passwd_pw_age=yes, ac_cv_struct_passwd_pw_age=no))
+
+if test "$ac_cv_struct_passwd_pw_age" = "yes"; then
+ AC_DEFINE(ATT_AGE)
+fi
+
+AC_CACHE_CHECK(for pw_comment in struct passwd,
+ac_cv_struct_passwd_pw_comment, AC_TRY_COMPILE([#include <pwd.h>],
+[ struct passwd pw; pw.pw_comment = ""; ],
+ac_cv_struct_passwd_pw_comment=yes, ac_cv_struct_passwd_pw_comment=no))
+
+if test "$ac_cv_struct_passwd_pw_comment" = "yes"; then
+ AC_DEFINE(ATT_COMMENT)
+fi
+
+AC_CACHE_CHECK(for pw_quota in struct passwd,
+ac_cv_struct_passwd_pw_quota, AC_TRY_COMPILE([#include <pwd.h>],
+[ struct passwd pw; pw.pw_quota = 0; ],
+ac_cv_struct_passwd_pw_quota=yes, ac_cv_struct_passwd_pw_quota=no))
+
+if test "$ac_cv_struct_passwd_pw_quota" = "yes"; then
+ AC_DEFINE(BSD_QUOTA)
+fi
+
+if test "$ac_cv_header_utmp_h" = "yes"; then
+ AC_CACHE_CHECK(for ut_host in struct utmp,
+ ac_cv_struct_utmp_ut_host, AC_TRY_COMPILE([#include <utmp.h>],
+ [ struct utmp ut; char *cp = ut.ut_host; ],
+ ac_cv_struct_utmp_ut_host=yes, ac_cv_struct_utmp_ut_host=no))
+
+ if test "$ac_cv_struct_utmp_ut_host" = "yes"; then
+ AC_DEFINE(UT_HOST)
+ fi
+
+ AC_CACHE_CHECK(for ut_user in struct utmp,
+ ac_cv_struct_utmp_ut_user, AC_TRY_COMPILE([#include <utmp.h>],
+ [ struct utmp ut; char *cp = ut.ut_user; ],
+ ac_cv_struct_utmp_ut_user=yes, ac_cv_struct_utmp_ut_user=no))
+
+ if test "$ac_cv_struct_utmp_ut_user" = "no"; then
+ AC_DEFINE(ut_user, ut_name)
+ fi
+fi
+
+if test "$ac_cv_header_lastlog_h" = "yes"; then
+ AC_CACHE_CHECK(for ll_host in struct lastlog,
+ ac_cv_struct_lastlog_ll_host, AC_TRY_COMPILE([#include <lastlog.h>],
+ [ struct lastlog ll; char *cp = ll.ll_host; ],
+ ac_cv_struct_lastlog_ll_host=yes, ac_cv_struct_lastlog_ll_host=no))
+
+ if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
+ AC_DEFINE(HAVE_LL_HOST)
+ fi
+fi
+
+dnl Checks for library functions.
+AC_TYPE_GETGROUPS
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_UTIME_NULL
+AC_FUNC_STRFTIME
+dnl Disabled for now, strtoday.c has problems with year 2000 or later
+dnl AC_CHECK_FUNCS(strptime)
+AC_CHECK_FUNCS(a64l fchmod fchown fsync getgroups gethostname getspnam)
+AC_CHECK_FUNCS(gettimeofday getusershell getutent initgroups lchown lckpwdf)
+AC_CHECK_FUNCS(lstat memcpy memset setgroups sigaction strchr updwtmp updwtmpx)
+
+AC_REPLACE_FUNCS(mkdir putgrent putpwent putspent rename rmdir)
+AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
+AC_REPLACE_FUNCS(snprintf strcasecmp strdup strerror strstr)
+
+AC_CHECK_FUNC(setpgrp)
+AC_FUNC_SETPGRP
+
+if test "$ac_cv_header_shadow_h" = "yes"; then
+AC_CACHE_CHECK(for working shadow group support,
+ac_cv_libc_shadowgrp, AC_TRY_RUN(
+[
+#include <shadow.h>
+main()
+{
+ struct sgrp *sg = sgetsgent("test:x::");
+ /* NYS libc on Red Hat 3.0.3 has broken shadow group support */
+ return !sg || !sg->sg_adm || !sg->sg_mem;
+}
+],
+ac_cv_libc_shadowgrp=yes,ac_cv_libc_shadowgrp=no,ac_cv_libc_shadowgrp=no))
+
+if test "$ac_cv_libc_shadowgrp" = "yes"; then
+ AC_DEFINE(HAVE_SHADOWGRP)
+fi
+fi
+
+AC_MSG_CHECKING(location of shared mail directory)
+for maildir in /var/spool/mail /var/mail /usr/spool/mail /usr/mail NONE; do
+ if test "$maildir" = "NONE"; then
+ AC_MSG_RESULT(None)
+ elif test -d $maildir; then
+ AC_DEFINE_UNQUOTED(MAIL_SPOOL_DIR, "$maildir")
+ AC_MSG_RESULT($maildir)
+ break
+ fi
+done
+
+AC_MSG_CHECKING(location of user mail file)
+for mailfile in Mailbox mailbox Mail mail .mail NONE; do
+ if test "$mailfile" = "NONE"; then
+ AC_MSG_RESULT(None)
+ elif test -f $HOME/$mailfile; then
+ AC_DEFINE_UNQUOTED(MAIL_SPOOL_FILE, "$mailfile")
+ AC_MSG_RESULT($mailfile)
+ break
+ fi
+done
+
+AC_MSG_CHECKING(location of utmp)
+for utmpdir in /var/run /var/adm /usr/adm /etc NONE; do
+ if test "$utmpdir" = "NONE"; then
+ AC_MSG_WARN(utmp file not found)
+ elif test -f $utmpdir/utmp; then
+ AC_DEFINE_UNQUOTED(_UTMP_FILE, "$utmpdir/utmp")
+ AC_MSG_RESULT($utmpdir)
+ break
+ fi
+done
+
+AC_MSG_CHECKING(location of faillog/lastlog/wtmp)
+for logdir in /var/log /var/adm /usr/adm /etc; do
+ if test -d $logdir; then
+ AC_DEFINE_UNQUOTED(_WTMP_FILE, "$logdir/wtmp")
+ AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$logdir/lastlog")
+ AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$logdir/faillog")
+ AC_MSG_RESULT($logdir)
+ break
+ fi
+done
+
+AC_MSG_CHECKING(location of the passwd program)
+if test -f /usr/bin/passwd; then
+ passwd_dir=/usr/bin
+else
+ passwd_dir=/bin
+fi
+AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$passwd_dir/passwd")
+AC_MSG_RESULT($passwd_dir)
+
+dnl XXX - quick hack, should disappear before anyone notices :).
+AC_DEFINE(SHADOWPWD)
+AC_DEFINE(USG)
+AC_DEFINE(AGING)
+AC_DEFINE(USE_SYSLOG)
+AC_DEFINE(RLOGIN)
+AC_DEFINE(RUSEROK, 0)
+AC_DEFINE(LOGIN_ACCESS)
+AC_DEFINE(SU_ACCESS)
+
+dnl Use our own version of getpass(), which handles long passwords
+dnl (unlike many systems which have a limit of 8 characters), and can
+dnl be interrupted with Ctrl-C (unlike Linux libc).
+AC_DEFINE(getpass, libshadow_getpass)
+
+AC_ARG_ENABLE(desrpc, [ --enable-desrpc try to use secure RPC in login (default if found)])
+dnl AC_ARG_ENABLE(md5crypt, [ --enable-md5crypt include MD5-compatible crypt function])
+AC_ARG_ENABLE(shadowgrp, [ --enable-shadowgrp enable shadow group support [default=yes]])
+
+AC_ARG_WITH(libcrack, [ --with-libcrack try to use libcrack (default if found)])
+AC_ARG_WITH(libcrypt, [ --with-libcrypt try to use libcrypt (default if found)])
+AC_ARG_WITH(libopie, [ --with-libopie use libopie for OPIE support])
+AC_ARG_WITH(libpam, [ --with-libpam use libpam for PAM support])
+AC_ARG_WITH(libskey, [ --with-libskey use libskey for S/Key support])
+AC_ARG_WITH(libtcfs, [ --with-libtcfs use libtcfs for TCFS support])
+
+dnl Check for some functions in libc first, only if not found check for
+dnl other libraries. This should prevent linking libnsl if not really
+dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
+
+AC_CHECK_FUNC(inet_ntoa, [], AC_CHECK_LIB(inet, inet_ntoa))
+AC_CHECK_FUNC(socket, [], AC_CHECK_LIB(socket, socket))
+AC_CHECK_FUNC(gethostbyname, [], AC_CHECK_LIB(nsl, gethostbyname))
+
+dnl XXX - getsecretkey() causes login to hang for 5 minutes on at least
+dnl one RH 4.0 system. Use --disable-desrpc if you have this problem.
+dnl Reported by Mohan Khurana <mohan@stealth.net>.
+
+if test "$enable_desrpc" != "no" -a "$ac_cv_header_rpc_key_prot_h" = "yes" ; then
+ AC_CHECK_FUNC(getsecretkey, AC_DEFINE(DES_RPC),
+ AC_CHECK_LIB(rpcsvc, getsecretkey, AC_DEFINE(DES_RPC)))
+fi
+
+if test "$enable_shadowgrp" != "no"; then
+ AC_DEFINE(SHADOWGRP)
+fi
+
+AC_SUBST(LIBCRYPT)
+if test "$with_libcrypt" != "no"; then
+ AC_CHECK_LIB(crypt, crypt, [AC_DEFINE(HAVE_LIBCRYPT) LIBCRYPT=-lcrypt])
+fi
+
+if test "$enable_md5crypt" = "yes"; then
+ LIBOBJS="$LIBOBJS md5.o md5crypt.o"
+ AC_DEFINE(MD5_CRYPT)
+fi
+
+AC_SUBST(LIBCRACK)
+if test "$with_libcrack" != "no"; then
+ echo "checking cracklib flavour, don't be surprised by the results"
+ AC_CHECK_LIB(crack, FascistCheck, AC_DEFINE(HAVE_LIBCRACK) LIBCRACK=-lcrack)
+ AC_CHECK_LIB(crack, FascistHistory, AC_DEFINE(HAVE_LIBCRACK_HIST))
+ AC_CHECK_LIB(crack, FascistHistoryPw, AC_DEFINE(HAVE_LIBCRACK_PW))
+fi
+
+AC_SUBST(LIBSKEY)
+AC_SUBST(LIBMD)
+if test "$with_libskey" = "yes"; then
+ AC_CHECK_LIB(md, MD5Init, LIBMD=-lmd)
+ AC_CHECK_LIB(skey, skeychallenge, AC_DEFINE(SKEY) LIBSKEY=-lskey, , $LIBMD $LIBCRYPT)
+elif test "$with_libopie" = "yes"; then
+ AC_CHECK_LIB(opie, opiechallenge, AC_DEFINE(OPIE) LIBSKEY=-lopie, , $LIBCRYPT)
+fi
+
+AC_SUBST(LIBTCFS)
+if test "$with_libtcfs" = "yes"; then
+ AC_CHECK_LIB(tcfs, tcfs_encrypt_key, AC_DEFINE(HAVE_TCFS) AC_DEFINE(TCFS_GDBM_SUPPORT) LIBTCFS="-ltcfs -lgdbm", , -lgdbm)
+fi
+
+AC_SUBST(LIBPAM)
+if test "$with_libpam" = "yes"; then
+ dnl AC_CHECK_LIB(pam, pam_start, AC_DEFINE(USE_PAM) LIBPAM=-lpam)
+ dnl the above doesn't work as there is no libpam.a (only .so)
+ dnl XXX - libpam_misc is probably Linux-PAM specific
+ LIBPAM="-lpam -lpam_misc -ldl"
+ AC_DEFINE(USE_PAM)
+ AC_CACHE_CHECK(whether pam_strerror needs two arguments,
+ ac_cv_pam_strerror_needs_two_args,
+ AC_TRY_COMPILE(
+ [#include <security/pam_appl.h>],
+ [ pam_handle_t *pamh; pam_strerror(pamh, PAM_SUCCESS); ],
+ ac_cv_pam_strerror_needs_two_args=yes,
+ ac_cv_pam_strerror_needs_two_args=no
+ )
+ )
+ if test "$ac_cv_pam_strerror_needs_two_args" = "yes"; then
+ AC_DEFINE(PAM_STRERROR_NEEDS_TWO_ARGS)
+ fi
+fi
+
+LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.o/.lo/g'`
+AC_SUBST(LTLIBOBJS)
+dnl LTALLOCA=`echo "$ALLOCA" | sed 's/\.o/.lo/g'`
+dnl AC_SUBST(LTALLOCA)
+
+AM_GNU_GETTEXT
+dnl AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+
+AC_OUTPUT(libmisc/Makefile man/Makefile man/pl/Makefile
+ lib/Makefile src/Makefile Makefile
+ contrib/Makefile debian/Makefile doc/Makefile etc/Makefile
+ intl/Makefile intl/po2tbl.sed po/Makefile.in
+ etc/pam.d/Makefile old/Makefile
+ redhat/Makefile redhat/shadow-utils.spec,
+ echo timestamp > stamp-h)
+
diff --git a/current/contrib/Makefile.am b/current/contrib/Makefile.am
new file mode 100644
index 00000000..ea24774e
--- /dev/null
+++ b/current/contrib/Makefile.am
@@ -0,0 +1,6 @@
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh \
+ atudel groupmems.shar pwdauth.c rpasswd.c shadow-anonftp.patch \
+ udbachk.v012.tgz
diff --git a/current/contrib/Makefile.in b/current/contrib/Makefile.in
new file mode 100644
index 00000000..4f546120
--- /dev/null
+++ b/current/contrib/Makefile.in
@@ -0,0 +1,212 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh atudel groupmems.shar pwdauth.c rpasswd.c shadow-anonftp.patch udbachk.v012.tgz
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = README Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps contrib/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = contrib
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/contrib/README b/current/contrib/README
new file mode 100644
index 00000000..c4d1bc03
--- /dev/null
+++ b/current/contrib/README
@@ -0,0 +1,10 @@
+People keep sending various adduser programs and scripts... They are
+all in this directory. I haven't tested them, use at your own risk.
+Anyway, the best one I've seen so far is adduser-3.x from Debian.
+
+atudel is a perl script to remove at jobs owned by the specified user
+(atrm in at-2.9 for Linux can't do that).
+
+udbachk.tgz is a passwd/group/shadow file integrity checker.
+
+--marekm
diff --git a/current/contrib/adduser-old.c b/current/contrib/adduser-old.c
new file mode 100644
index 00000000..f924b36e
--- /dev/null
+++ b/current/contrib/adduser-old.c
@@ -0,0 +1,300 @@
+/****
+** 03/17/96
+** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
+** --marekm
+**
+** 02/26/96
+** modified to call shadow utils (useradd,chage,passwd) on shadowed
+** systems - Cristian Gafton, gafton@sorosis.ro
+**
+** 6/27/95
+** shadow-adduser 1.4:
+**
+** now it copies the /etc/skel dir into the person's dir,
+** makes the mail folders, changed some defaults and made a 'make
+** install' just for the hell of it.
+**
+** Greg Gallagher
+** CIN.Net
+**
+** 1/28/95
+** shadow-adduser 1.3:
+**
+** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart
+** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
+** It was such a stupid bug that I would have never seen it myself.
+**
+** Brandon
+*****
+** 01/27/95
+**
+** shadow-adduser 1.2:
+** I took the C source from adduser-shadow (credits are below) and made
+** it a little more worthwhile. Many small changes... Here's
+** the ones I can remember:
+**
+** Removed support for non-shadowed systems (if you don't have shadow,
+** use the original adduser, don't get this shadow version!)
+** Added support for the correct /etc/shadow fields (Min days before
+** password change, max days before password change, Warning days,
+** and how many days from expiry date does the account go invalid)
+** The previous version just left all of those fields blank.
+** There is still one field left (expiry date for the account, period)
+** which I have left blank because I do not use it and didn't want to
+** spend any more time on this. I'm sure someone will put it in and
+** tack another plethora of credits on here. :)
+** Added in the password date field, which should always reflect the last
+** date the password was changed, for expiry purposes. "passwd" always
+** updates this field, so the adduser program should set it up right
+** initially (or a user could keep thier initial password forever ;)
+** The number is in days since Jan 1st, 1970.
+**
+** Have fun with it, and someone please make
+** a real version(this is still just a hack)
+** for us all to use (and Email it to me???)
+**
+** Brandon
+** photon@usis.com
+**
+*****
+** adduser 1.0: add a new user account (For systems not using shadow)
+** With a nice little interface and a will to do all the work for you.
+**
+** Craig Hagan
+** hagan@opine.cs.umass.edu
+**
+** Modified to really work, look clean, and find unused uid by Chris Cappuccio
+** chris@slinky.cs.umass.edu
+**
+*****
+**
+** 01/19/95
+**
+** FURTHER modifications to enable shadow passwd support (kludged, but
+** no more so than the original) by Dan Crowson - dcrowson@mo.net
+**
+** Search on DAN for all changes...
+**
+*****
+**
+** cc -O -o adduser adduser.c
+** Use gcc if you have it... (political reasons beyond my control) (chris)
+**
+** I've gotten this program to work with success under Linux (without
+** shadow) and SunOS 4.1.3. I would assume it should work pretty well
+** on any system that uses no shadow. (chris)
+**
+** If you have no crypt() then try
+** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
+** I'm not sure how login operates with no crypt()... I guess
+** the same way we're doing it here.
+*/
+
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
+#define DEFAULT_HOME "/home"
+#define USERADD_PATH "/usr/sbin/useradd"
+#define CHAGE_PATH "/usr/sbin/chage"
+#define PASSWD_PATH "/usr/bin/passwd"
+#define DEFAULT_GROUP 100
+
+#define DEFAULT_MAX_PASS 60
+#define DEFAULT_WARN_PASS 10
+/* if you use this feature, you will get a lot of complaints from users
+ who rarely use their accounts :) (something like 3 months would be
+ more reasonable) --marekm */
+#define DEFAULT_USER_DIE /* 10 */ 0
+
+void main()
+{
+ char foo[32];
+ char uname[9],person[32],dir[32],shell[32];
+ unsigned int group,min_pass,max_pass,warn_pass,user_die;
+ /* the group and uid of the new user */
+ int bad=0,done=0,correct=0,gets_warning=0;
+ char cmd[255];
+ struct group *grp;
+
+ /* flags, in order:
+ * bad to see if the username is in /etc/passwd, or if strange stuff has
+ * been typed if the user might be put in group 0
+ * done allows the program to exit when a user has been added
+ * correct loops until a password is found that isn't in /etc/passwd
+ * gets_warning allows the fflush to be skipped for the first gets
+ * so that output is still legible
+ */
+
+ /* The real program starts HERE! */
+
+ if(geteuid()!=0)
+ {
+ printf("It seems you don't have access to add a new user. Try\n");
+ printf("logging in as root or su root to gain super-user access.\n");
+ exit(1);
+ }
+
+ /* Sanity checks
+ */
+
+ if (!(grp=getgrgid(DEFAULT_GROUP))){
+ printf("Error: the default group %d does not exist on this system!\n",
+ DEFAULT_GROUP);
+ printf("adduser must be recompiled.\n");
+ exit(1);
+ };
+
+ while(!correct) { /* loop until a "good" uname is chosen */
+ while(!done) {
+ printf("\nLogin to add (^C to quit): ");
+ if(gets_warning) /* if the warning was already shown */
+ fflush(stdout); /* fflush stdout, otherwise set the flag */
+ else
+ gets_warning=1;
+
+ gets(uname);
+ if(!strlen(uname)) {
+ printf("Empty input.\n");
+ done=0;
+ continue;
+ };
+
+ /* what I saw here before made me think maybe I was running DOS */
+ /* might this be a solution? (chris) */
+ if (getpwnam(uname) != NULL) {
+ printf("That name is in use, choose another.\n");
+ done=0;
+ } else
+ done=1;
+ }; /* done, we have a valid new user name */
+
+ /* all set, get the rest of the stuff */
+ printf("\nEditing information for new user [%s]\n",uname);
+
+ printf("\nFull Name [%s]: ",uname);
+ gets(person);
+ if (!strlen(person)) {
+ bzero(person,sizeof(person));
+ strcpy(person,uname);
+ };
+
+ do {
+ bad=0;
+ printf("GID [%d]: ",DEFAULT_GROUP);
+ gets(foo);
+ if (!strlen(foo))
+ group=DEFAULT_GROUP;
+ else
+ if (isdigit (*foo)) {
+ group = atoi(foo);
+ if (! (grp = getgrgid (group))) {
+ printf("unknown gid %s\n",foo);
+ group=DEFAULT_GROUP;
+ bad=1;
+ };
+ } else
+ if ((grp = getgrnam (foo)))
+ group = grp->gr_gid;
+ else {
+ printf("unknown group %s\n",foo);
+ group=DEFAULT_GROUP;
+ bad=1;
+ }
+ if (group==0){ /* You're not allowed to make root group users! */
+ printf("Creation of root group users not allowed (must be done by hand)\n");
+ group=DEFAULT_GROUP;
+ bad=1;
+ };
+ } while(bad);
+
+
+ fflush(stdin);
+
+ printf("\nIf home dir ends with a / then [%s] will be appended to it\n",uname);
+ printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname);
+ fflush(stdout);
+ gets(dir);
+ if (!strlen(dir)) { /* hit return */
+ sprintf(dir,"%s/%s",DEFAULT_HOME,uname);
+ fflush(stdin);
+ } else
+ if (dir[strlen(dir)-1]=='/')
+ sprintf(dir,"%s%s",dir,uname);
+
+ printf("\nShell [%s]: ",DEFAULT_SHELL);
+ fflush(stdout);
+ gets(shell);
+ if (!strlen(shell))
+ sprintf(shell,"%s",DEFAULT_SHELL);
+
+ printf("\nMin. Password Change Days [0]: ");
+ gets(foo);
+ min_pass=atoi(foo);
+
+ printf("Max. Password Change Days [%d]: ",DEFAULT_MAX_PASS);
+ gets(foo);
+ if (strlen(foo) > 1)
+ max_pass = atoi(foo);
+ else
+ max_pass = DEFAULT_MAX_PASS;
+
+ printf("Password Warning Days [%d]: ",DEFAULT_WARN_PASS);
+ gets(foo);
+ warn_pass = atoi(foo);
+ if (warn_pass==0)
+ warn_pass = DEFAULT_WARN_PASS;
+
+ printf("Days after Password Expiry for Account Locking [%d]: ",DEFAULT_USER_DIE);
+ gets(foo);
+ user_die = atoi(foo);
+ if (user_die == 0)
+ user_die = DEFAULT_USER_DIE;
+
+ printf("\nInformation for new user [%s] [%s]:\n",uname,person);
+ printf("Home directory: [%s] Shell: [%s]\n",dir,shell);
+ printf("GID: [%d]\n",group);
+ printf("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
+ min_pass,max_pass,warn_pass,user_die);
+ printf("\nIs this correct? [y/N]: ");
+ fflush(stdout);
+ gets(foo);
+
+ done=bad=correct=(foo[0]=='y'||foo[0]=='Y');
+
+ if(bad!=1)
+ printf("\nUser [%s] not added\n",uname);
+ }
+
+ bzero(cmd,sizeof(cmd));
+ sprintf(cmd,"%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
+ USERADD_PATH,group,dir,shell,person,uname);
+ printf("Calling useradd to add new user:\n%s\n",cmd);
+ if(system(cmd)){
+ printf("User add failed!\n");
+ exit(errno);
+ };
+ bzero(cmd,sizeof(cmd));
+ sprintf(cmd,"%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
+ min_pass,max_pass,warn_pass,user_die,uname);
+ printf("%s\n",cmd);
+ if(system(cmd)){
+ printf("There was an error setting password expire values\n");
+ exit(errno);
+ };
+ bzero(cmd,sizeof(cmd));
+ sprintf(cmd,"%s %s",PASSWD_PATH,uname);
+ system(cmd);
+ printf("\nDone.\n");
+}
+
diff --git a/current/contrib/adduser.c b/current/contrib/adduser.c
new file mode 100644
index 00000000..f303a41d
--- /dev/null
+++ b/current/contrib/adduser.c
@@ -0,0 +1,502 @@
+/****
+** 04/21/96
+** hacked even more, replaced gets() with something slightly harder to buffer
+** overflow. Added support for setting a default quota on new account, with
+** edquota -p. Other cleanups for security, I let some users run adduser suid
+** root to add new accounts. (overflow checks, clobber environment, valid
+** shell checks, restrictions on gid + home dir settings).
+
+** Added max. username length. Used syslog() a bit for important events.
+** Support to immediately expire account with passwd -e.
+
+** Called it version 2.0! Because I felt like it!
+
+** -- Chris, chris@ferret.lmh.ox.ac.uk
+
+** 03/17/96
+** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
+** --marekm
+**
+** 02/26/96
+** modified to call shadow utils (useradd,chage,passwd) on shadowed
+** systems - Cristian Gafton, gafton@sorosis.ro
+**
+** 6/27/95
+** shadow-adduser 1.4:
+**
+** now it copies the /etc/skel dir into the person's dir,
+** makes the mail folders, changed some defaults and made a 'make
+** install' just for the hell of it.
+**
+** Greg Gallagher
+** CIN.Net
+**
+** 1/28/95
+** shadow-adduser 1.3:
+**
+** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart
+** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
+** It was such a stupid bug that I would have never seen it myself.
+**
+** Brandon
+*****
+** 01/27/95
+**
+** shadow-adduser 1.2:
+** I took the C source from adduser-shadow (credits are below) and made
+** it a little more worthwhile. Many small changes... Here's
+** the ones I can remember:
+**
+** Removed support for non-shadowed systems (if you don't have shadow,
+** use the original adduser, don't get this shadow version!)
+** Added support for the correct /etc/shadow fields (Min days before
+** password change, max days before password change, Warning days,
+** and how many days from expiry date does the account go invalid)
+** The previous version just left all of those fields blank.
+** There is still one field left (expiry date for the account, period)
+** which I have left blank because I do not use it and didn't want to
+** spend any more time on this. I'm sure someone will put it in and
+** tack another plethora of credits on here. :)
+** Added in the password date field, which should always reflect the last
+** date the password was changed, for expiry purposes. "passwd" always
+** updates this field, so the adduser program should set it up right
+** initially (or a user could keep thier initial password forever ;)
+** The number is in days since Jan 1st, 1970.
+**
+** Have fun with it, and someone please make
+** a real version(this is still just a hack)
+** for us all to use (and Email it to me???)
+**
+** Brandon
+** photon@usis.com
+**
+*****
+** adduser 1.0: add a new user account (For systems not using shadow)
+** With a nice little interface and a will to do all the work for you.
+**
+** Craig Hagan
+** hagan@opine.cs.umass.edu
+**
+** Modified to really work, look clean, and find unused uid by Chris Cappuccio
+** chris@slinky.cs.umass.edu
+**
+*****
+**
+** 01/19/95
+**
+** FURTHER modifications to enable shadow passwd support (kludged, but
+** no more so than the original) by Dan Crowson - dcrowson@mo.net
+**
+** Search on DAN for all changes...
+**
+*****
+**
+** cc -O -o adduser adduser.c
+** Use gcc if you have it... (political reasons beyond my control) (chris)
+**
+** I've gotten this program to work with success under Linux (without
+** shadow) and SunOS 4.1.3. I would assume it should work pretty well
+** on any system that uses no shadow. (chris)
+**
+** If you have no crypt() then try
+** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
+** I'm not sure how login operates with no crypt()... I guess
+** the same way we're doing it here.
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <syslog.h>
+
+#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
+ * immediately upon next login */
+#define HAVE_QUOTAS /* Obvious */
+#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change
+ * password expiry values (if running suid root) */
+
+#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */
+#define LOGGING /* If we want to log various things to syslog */
+#define MAX_USRNAME 8 /* Longer usernames seem to work on my system....
+ * But they're probably a poor idea */
+
+
+#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
+#define DEFAULT_HOME "/home"
+#define USERADD_PATH "/usr/sbin/useradd"
+#define CHAGE_PATH "/usr/bin/chage"
+#define PASSWD_PATH "/usr/bin/passwd"
+#define EDQUOTA_PATH "/usr/sbin/edquota"
+#define QUOTA_DEFAULT "defuser"
+#define DEFAULT_GROUP 100
+
+#define DEFAULT_MIN_PASS 0
+#define DEFAULT_MAX_PASS 100
+#define DEFAULT_WARN_PASS 14
+#define DEFAULT_USER_DIE 366
+
+void safeget (char *, int);
+
+void
+main (void)
+{
+ char foo[32];
+ char usrname[32], person[32], dir[32], shell[32];
+ unsigned int group, min_pass, max_pass, warn_pass, user_die;
+ /* the group and uid of the new user */
+ int bad = 0, done = 0, correct = 0, olduid;
+ char cmd[255];
+ struct group *grp;
+
+ /* flags, in order:
+ * bad to see if the username is in /etc/passwd, or if strange stuff has
+ * been typed if the user might be put in group 0
+ * done allows the program to exit when a user has been added
+ * correct loops until a username is found that isn't in /etc/passwd
+ */
+
+ /* The real program starts HERE! */
+
+ if (geteuid () != 0)
+ {
+ printf ("It seems you don't have access to add a new user. Try\n");
+ printf ("logging in as root or su root to gain super-user access.\n");
+ exit (1);
+ }
+
+ /* Sanity checks
+ */
+
+#ifdef LOGGING
+ openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
+ syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
+#endif
+
+ if (!(grp = getgrgid (DEFAULT_GROUP)))
+ {
+ printf ("Error: the default group %d does not exist on this system!\n",
+ DEFAULT_GROUP);
+ printf ("adduser must be recompiled.\n");
+#ifdef LOGGING
+ syslog (LOG_ERR, "warning: failed. no such default group\n");
+ closelog ();
+#endif
+ exit (1);
+ };
+
+ while (!correct)
+ { /* loop until a "good" usrname is chosen */
+ while (!done)
+ {
+ printf ("\nLogin to add (^C to quit): ");
+ fflush (stdout);
+
+ safeget (usrname, sizeof (usrname));
+
+ if (!strlen (usrname))
+ {
+ printf ("Empty input.\n");
+ done = 0;
+ continue;
+ };
+
+ /* what I saw here before made me think maybe I was running DOS */
+ /* might this be a solution? (chris) */
+ if (strlen (usrname) > MAX_USRNAME)
+ {
+ printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
+ done = 0;
+ }
+ else if (getpwnam (usrname) != NULL)
+ {
+ printf ("That name is in use, choose another.\n");
+ done = 0;
+ }
+ else if (strchr (usrname, ' ') != NULL)
+ {
+ printf ("No spaces in username!!\n");
+ done = 0;
+ }
+ else
+ done = 1;
+ }; /* done, we have a valid new user name */
+
+ /* all set, get the rest of the stuff */
+ printf ("\nEditing information for new user [%s]\n", usrname);
+
+ printf ("\nFull Name [%s]: ", usrname);
+ fflush (stdout);
+ safeget (person, sizeof (person));
+ if (!strlen (person))
+ {
+ bzero (person, sizeof (person));
+ strcpy (person, usrname);
+ };
+
+ if (getuid () == 0)
+ {
+ do
+ {
+ bad = 0;
+ printf ("GID [%d]: ", DEFAULT_GROUP);
+ fflush (stdout);
+ safeget (foo, sizeof (foo));
+ if (!strlen (foo))
+ group = DEFAULT_GROUP;
+ else if (isdigit (*foo))
+ {
+ group = atoi (foo);
+ if (!(grp = getgrgid (group)))
+ {
+ printf ("unknown gid %s\n", foo);
+ group = DEFAULT_GROUP;
+ bad = 1;
+ };
+ }
+ else if ((grp = getgrnam (foo)))
+ group = grp->gr_gid;
+ else
+ {
+ printf ("unknown group %s\n", foo);
+ group = DEFAULT_GROUP;
+ bad = 1;
+ }
+ if (group == 0)
+ { /* You're not allowed to make root group users! */
+ printf ("Creation of root group users not allowed (must be done by hand)\n");
+ group = DEFAULT_GROUP;
+ bad = 1;
+ };
+ }
+ while (bad);
+ }
+ else
+ {
+ printf ("Group will be default of: %d\n", DEFAULT_GROUP);
+ group = DEFAULT_GROUP;
+ }
+
+ if (getuid () == 0)
+ {
+ printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
+ printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
+ fflush (stdout);
+ safeget (dir, sizeof (dir));
+ if (!strlen (dir))
+ { /* hit return */
+ sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
+ }
+ else if (dir[strlen (dir) - 1] == '/')
+ sprintf (dir, "%s%s", dir, usrname);
+ }
+ else
+ {
+ printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
+ sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
+ }
+
+ printf ("\nShell [%s]: ", DEFAULT_SHELL);
+ fflush (stdout);
+ safeget (shell, sizeof (shell));
+ if (!strlen (shell))
+ sprintf (shell, "%s", DEFAULT_SHELL);
+ else
+ {
+ char *sh;
+ int ok = 0;
+#ifdef HAVE_GETUSERSHELL
+ setusershell ();
+ while ((sh = getusershell ()) != NULL)
+ if (!strcmp (shell, sh))
+ ok = 1;
+ endusershell ();
+#endif
+ if (!ok)
+ {
+ if (getuid () == 0)
+ printf ("Warning: root allowed non standard shell\n");
+ else
+ {
+ printf ("Shell NOT in /etc/shells, DEFAULT used\n");
+ sprintf (shell, "%s", DEFAULT_SHELL);
+ }
+ }
+ }
+
+#ifdef EXPIRE_VALS_SET
+ if (getuid () == 0)
+ {
+#endif
+ printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
+ fflush (stdout);
+ safeget (foo, sizeof (foo));
+ if (strlen (foo) > 1)
+ min_pass = DEFAULT_MIN_PASS;
+ else
+ min_pass = atoi (foo);
+
+ printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
+ fflush (stdout);
+ safeget (foo, sizeof (foo));
+ if (strlen (foo) > 1)
+ max_pass = atoi (foo);
+ else
+ max_pass = DEFAULT_MAX_PASS;
+
+ printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
+ fflush (stdout);
+ safeget (foo, sizeof (foo));
+ warn_pass = atoi (foo);
+ if (warn_pass == 0)
+
+ warn_pass = DEFAULT_WARN_PASS;
+
+ printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
+ fflush (stdout);
+ safeget (foo, sizeof (foo));
+ user_die = atoi (foo);
+ if (user_die == 0)
+ user_die = DEFAULT_USER_DIE;
+
+#ifdef EXPIRE_VALS_SET
+ }
+ else
+ {
+ printf ("\nSorry, account expiry values are set.\n");
+ user_die = DEFAULT_USER_DIE;
+ warn_pass = DEFAULT_WARN_PASS;
+ max_pass = DEFAULT_MAX_PASS;
+ min_pass = DEFAULT_MIN_PASS;
+ }
+#endif
+
+ printf ("\nInformation for new user [%s] [%s]:\n", usrname, person);
+ printf ("Home directory: [%s] Shell: [%s]\n", dir, shell);
+ printf ("GID: [%d]\n", group);
+ printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
+ min_pass, max_pass, warn_pass, user_die);
+ printf ("\nIs this correct? [y/N]: ");
+ fflush (stdout);
+ safeget (foo, sizeof (foo));
+
+ done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
+
+ if (bad != 1)
+ printf ("\nUser [%s] not added\n", usrname);
+ }
+
+ /* Clobber the environment, I run this suid root sometimes to let
+ * non root privileged accounts add users --chris */
+
+ *environ = NULL;
+
+ bzero (cmd, sizeof (cmd));
+ sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
+ USERADD_PATH, group, dir, shell, person, usrname);
+ printf ("Calling useradd to add new user:\n%s\n", cmd);
+ if (system (cmd))
+ {
+ printf ("User add failed!\n");
+#ifdef LOGGING
+ syslog (LOG_ERR, "could not add new user\n");
+ closelog ();
+#endif
+ exit (errno);
+ };
+
+ olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root
+ */
+ setuid (0);
+
+ bzero (cmd, sizeof (cmd));
+
+ /* Chage runs suid root. => we need ruid root to run it with
+ * anything other than chage -l
+ */
+
+ sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
+ min_pass, max_pass, warn_pass, user_die, usrname);
+ printf ("%s\n", cmd);
+ if (system (cmd))
+ {
+ printf ("There was an error setting password expire values\n");
+#ifdef LOGGING
+ syslog (LOG_ERR, "password expire values could not be set\n");
+#endif
+ };
+
+ /* I want to add a user completely with one easy command --chris */
+
+#ifdef HAVE_QUOTAS
+ bzero (cmd, sizeof (cmd));
+ sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
+ printf ("%s\n", cmd);
+ if (system (cmd))
+ {
+ printf ("\nWarning: error setting quota\n");
+#ifdef LOGGING
+ syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
+#endif /* LOGGING */
+ }
+ else
+ printf ("\nDefault quota set.\n");
+#endif /* HAVE_QUOTAS */
+
+ bzero (cmd, sizeof (cmd));
+ sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
+ if (system (cmd))
+ {
+ printf ("\nWarning: error setting password\n");
+#ifdef LOGGING
+ syslog (LOG_ERR, "warning: password set failed!\n");
+#endif
+ }
+#ifdef IMMEDIATE_CHANGE
+ bzero (cmd, sizeof (cmd));
+ sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
+ if (system (cmd))
+ {
+ printf ("\nWarning: error expiring password\n");
+#ifdef LOGGING
+ syslog (LOG_ERR, "warning: password expire failed!\n");
+#endif /* LOGGING */
+ }
+#endif /* IMMEDIATE_CHANGE */
+
+ setuid (olduid);
+
+#ifdef LOGGING
+ closelog ();
+#endif
+
+ printf ("\nDone.\n");
+}
+
+void
+safeget (char *buf, int maxlen)
+{
+ int c, i = 0, bad = 0;
+ char *bstart = buf;
+ while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
+ {
+ bad = (!isalnum (c) && (c != '_') && (c != ' '));
+ *(buf++) = (char) c;
+ }
+ *buf = '\0';
+
+ if (bad)
+ {
+ printf ("\nString contained banned character. Please stick to alphanumerics.\n");
+ *bstart = '\0';
+ }
+}
+
diff --git a/current/contrib/adduser.sh b/current/contrib/adduser.sh
new file mode 100755
index 00000000..0efb27a3
--- /dev/null
+++ b/current/contrib/adduser.sh
@@ -0,0 +1,90 @@
+#!/bin/sh
+# adduser script for use with shadow passwords and useradd command.
+# by Hrvoje Dogan <hdogan@student.math.hr>, Dec 1995.
+
+echo -n "Login name for new user []:"
+read LOGIN
+if [ -z $LOGIN ]
+then echo "Come on, man, you can't leave the login field empty...";exit
+fi
+echo
+echo -n "User id for $LOGIN [ defaults to next available]:"
+read ID
+GUID="-u $ID"
+if [ -z $ID ]
+then GUID=""
+fi
+
+echo
+echo -n "Initial group for $LOGIN [users]:"
+read GID
+GGID="-g $GID"
+if [ -z $GID ]
+then GGID=""
+fi
+
+echo
+echo -n "Additional groups for $LOGIN []:"
+read AGID
+GAGID="-G $AGID"
+if [ -z $AGID ]
+then GAGID=""
+fi
+
+echo
+echo -n "$LOGIN's home directory [/home/$LOGIN]:"
+read HME
+GHME="-d $HME"
+if [ -z $HME ]
+then GHME=""
+fi
+
+echo
+echo -n "$LOGIN's shell [/bin/bash]:"
+read SHL
+GSHL="-s $SHL"
+if [ -z $SHL ]
+then GSHL=""
+fi
+
+echo
+echo -n "$LOGIN's account expiry date (MM/DD/YY) []:"
+read EXP
+GEXP="-e $EXP"
+if [ -z $EXP ]
+then GEXP=""
+fi
+echo
+echo OK, I'm about to make a new account. Here's what you entered so far:
+echo New login name: $LOGIN
+if [ -z $GUID ]
+then echo New UID: [Next available]
+else echo New UID: $UID
+fi
+if [ -z $GGID ]
+then echo Initial group: users
+else echo Initial group: $GID
+fi
+if [ -z $GAGID ]
+then echo Additional groups: [none]
+else echo Additional groups: $AGID
+fi
+if [ -z $GHME ]
+then echo Home directory: /home/$LOGIN
+else echo Home directory: $HME
+fi
+if [ -z $GSHL ]
+then echo Shell: /bin/bash
+else echo Shell: $SHL
+fi
+if [ -z $GEXP ]
+then echo Expiry date: [no expiration]
+else echo Expiry date: $EXP
+fi
+echo "This is it... if you want to bail out, you'd better do it now."
+read FOO
+echo Making new account...
+/usr/sbin/useradd $GHME -m $GEXP $GGID $GAGID $GSHL $GUID $LOGIN
+/usr/bin/chfn $LOGIN
+/usr/bin/passwd $LOGIN
+echo "Done..."
diff --git a/current/contrib/adduser2.sh b/current/contrib/adduser2.sh
new file mode 100755
index 00000000..a2b36b25
--- /dev/null
+++ b/current/contrib/adduser2.sh
@@ -0,0 +1,743 @@
+#!/bin/bash
+#
+# adduser Interactive user adding program.
+#
+# Copyright (C) 1996 Petri Mattila, Prihateam Networks
+# petri@prihateam.fi
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# Changes:
+# 220496 v0.01 Initial version
+# 230496 v0.02 More checks, embolden summary
+# 240496 Even more checks
+# 250496 Help with ?
+# 040596 v0.03 Cleanups
+# 050596 v0.04 Bug fixes, expire date checks
+# 070596 v0.05 Iso-latin-1 names
+#
+
+## Defaults
+
+# default groups
+def_group="users"
+def_other_groups=""
+
+# default home directory
+def_home_dir=/home/users
+
+# default shell
+def_shell=/bin/tcsh
+
+# Defaul expiration date (mm/dd/yy)
+def_expire=""
+
+# default dates
+def_pwd_min=0
+def_pwd_max=90
+def_pwd_warn=14
+def_pwd_iact=14
+
+
+# possible UIDs
+uid_low=1000
+uid_high=64000
+
+# skel directory
+skel=/etc/skel
+
+# default mode for home directory
+def_mode=711
+
+# Regex, that the login name must meet, only ANSI characters
+login_regex='^[0-9a-zA-Z_-]*$'
+
+# Regex, that the user name must meet
+# ANSI version
+##name_regex='^[0-9a-zA-Z_-\ ]*$'
+# ISO-LATIN-1 version
+name_regex='^[0-9a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ_-\ ]*$'
+
+# set PATH
+export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
+
+# Some special characters
+case "$TERM" in
+ vt*|ansi*|con*|xterm*|linux*)
+ S='' # start embolden
+ E='' # end embolden
+ ;;
+ *)
+ S=''
+ E=''
+ ;;
+esac
+
+
+## Functions
+
+check_root() {
+ if test "$EUID" -ne 0
+ then
+ echo "You must be root to run this program."
+ exit 1
+ fi
+}
+
+check_user() {
+ local usr pwd uid gid name home sh
+
+ cat /etc/passwd | (
+ while IFS=":" read usr pwd uid gid name home sh
+ do
+ if test "$1" = "${usr}"
+ then
+ return 1
+ fi
+ done
+ return 0
+ )
+}
+
+check_group() {
+ local read grp pwd gid members
+
+ cat /etc/group | (
+ while IFS=":" read grp pwd gid members
+ do
+ if test "$1" = "${grp}"
+ then
+ return 1
+ fi
+ done
+ return 0
+ )
+}
+
+check_other_groups() {
+ local grp check IFS
+
+ check="$1"
+ IFS=","
+
+ set ${check}
+ for grp
+ do
+ if check_group "${grp}"
+ then
+ echo "Group ${grp} does not exist."
+ return 1
+ fi
+ done
+ return 0
+}
+
+check_uid() {
+ local usr pwd uid gid name home sh
+
+ cat /etc/passwd | (
+ while IFS=":" read usr pwd uid gid name home sh
+ do
+ if test "$1" = "${uid}"
+ then
+ return 1
+ fi
+ done
+ return 0
+ )
+}
+
+read_yn() {
+ local ans ynd
+
+ ynd="$1"
+
+ while :
+ do
+ read ans
+ case "${ans}" in
+ "") return ${ynd} ;;
+ [nN]) return 1 ;;
+ [yY]) return 0 ;;
+ *) echo -n "Y or N, please ? " ;;
+ esac
+ done
+}
+
+read_login() {
+ echo
+ while :
+ do
+ echo -n "Login: ${def_login:+[${def_login}] }"
+ read login
+
+ if test "${login}" = '?'
+ then
+ less /etc/passwd
+ echo
+ continue
+ fi
+
+ if test -z "${login}" -a -n "${def_login}"
+ then
+ login="${def_login}"
+ echo "Using ${login}"
+ return
+ fi
+
+ if test "${#login}" -gt 8
+ then
+ echo "Login must be at most 8 characters long"
+ continue
+ fi
+
+ if test "${#login}" -lt 2
+ then
+ echo "Login must be at least 2 characters long"
+ continue
+ fi
+
+ if ! expr "${login}" : "${login_regex}" &> /dev/null
+ then
+ echo "Please use letters, numbers and special characters _-,."
+ continue
+ fi
+
+ if ! check_user "${login}"
+ then
+ echo "Username ${login} is already in use"
+ continue
+ fi
+
+ def_login="${login}"
+ return
+ done
+}
+
+read_name () {
+ echo
+ while :
+ do
+ echo -n "Real name: ${def_name:+[${def_name}] }"
+ read name
+
+ if test "${name}" = '?'
+ then
+ less /etc/passwd
+ echo
+ continue
+ fi
+
+ if test -z "${name}" -a -n "${def_name}"
+ then
+ name="${def_name}"
+ echo "Using ${name}"
+ fi
+
+ if test "${#name}" -gt 32
+ then
+ echo "Name should be at most 32 characters long"
+ continue
+ fi
+
+ if ! expr "${name}" : "${name_regex}" &> /dev/null
+ then
+ echo "Please use letters, numbers, spaces and special characters ,._-"
+ continue
+ fi
+
+ def_name="${name}"
+ return
+ done
+}
+
+read_home() {
+ local x
+
+ echo
+ while :
+ do
+ echo -n "Home Directory: [${def_home_dir}/${login}] "
+ read home
+
+ if test -z "${home}"
+ then
+ home="${def_home_dir}/${login}"
+ echo "Using ${home}"
+ fi
+
+ if ! expr "${home}" : '^[0-9a-zA-Z,._-\/]*$' &> /dev/null
+ then
+ echo "Please use letters, numbers, spaces and special characters ,._-/"
+ continue
+ fi
+
+ x="$(basename ${home})"
+ if test "${x}" != "${login}"
+ then
+ echo "Warning: you are about to use different login name and home directory."
+ fi
+
+ x="$(dirname ${home})"
+ if ! test -d "${x}"
+ then
+ echo "Directory ${x} does not exist."
+ echo "If you still want to use it, please make it manually."
+ continue
+ fi
+
+ def_home_dir="${x}"
+ return
+ done
+}
+
+read_shell () {
+ local x
+
+ echo
+ while :
+ do
+ echo -n "Shell: [${def_shell}] "
+ read shell
+
+ if test -z "${shell}"
+ then
+ shell="${def_shell}"
+ echo "Using ${shell}"
+ fi
+
+ for x in $(cat /etc/shells)
+ do
+ if test "${x}" = "${shell}"
+ then
+ def_shell="${shell}"
+ return
+ fi
+ done
+
+ echo "Possible shells are:"
+ cat /etc/shells
+ done
+}
+
+read_group () {
+ echo
+ while :
+ do
+ echo -n "Group: [${def_group}] "
+ read group
+
+ if test -z "${group}"
+ then
+ group="${def_group}"
+ echo "Using ${group}"
+ fi
+
+ if test "${group}" = '?'
+ then
+ less /etc/group
+ echo
+ continue
+ fi
+
+ if check_group "${group}"
+ then
+ echo "Group ${group} does not exist."
+ continue
+ fi
+
+ def_group="${group}"
+ return
+ done
+}
+
+read_other_groups () {
+ echo
+ while :
+ do
+ echo -n "Other groups: [${def_og:-none}] "
+ read other_groups
+
+ if test "${other_groups}" = '?'
+ then
+ less /etc/group
+ echo
+ continue
+ fi
+
+ if test -z "${other_groups}"
+ then
+ if test -n "${def_og}"
+ then
+ other_groups="${def_og}"
+ echo "Using ${other_groups}"
+ else
+ echo "No other groups"
+ return
+ fi
+ fi
+
+
+ if ! check_other_groups "${other_groups}"
+ then
+ continue
+ fi
+
+ def_og="${other_groups}"
+ return
+ done
+}
+
+read_uid () {
+ echo
+ while :
+ do
+ echo -n "uid: [first free] "
+ read uid
+
+ if test -z "${uid}"
+ then
+ echo "Using first free UID."
+ return
+ fi
+
+ if test "${uid}" = '?'
+ then
+ less /etc/passwd
+ echo
+ continue
+ fi
+
+ if ! expr "${uid}" : '^[0-9]+$' &> /dev/null
+ then
+ echo "Please use numbers only."
+ continue
+ fi
+ if test "${uid}" -lt "${uid_low}"
+ then
+ echo "UID must be greater than ${uid_low}"
+ continue
+ fi
+ if test "${uid}" -gt "${uid_high}"
+ then
+ echo "UID must be smaller than ${uid_high}"
+ continue
+ fi
+ if ! check_uid "${uid}"
+ then
+ echo "UID ${uid} is already in use"
+ continue
+ fi
+
+ return
+ done
+}
+
+read_max_valid_days() {
+ echo
+ while :
+ do
+ echo -en "Maximum days between password changes: [${def_pwd_max}] "
+ read max_days
+
+ if test -z "${max_days}"
+ then
+ max_days="${def_pwd_max}"
+ echo "Using ${max_days}"
+ return
+ fi
+
+ if ! expr "${max_days}" : '^[0-9]+$' &> /dev/null
+ then
+ echo "Please use numbers only."
+ continue
+ fi
+ if test "${max_days}" -lt 7
+ then
+ echo "Warning: you are using a value shorter than a week."
+ fi
+
+ def_pwd_max="${max_days}"
+ return
+ done
+}
+
+read_min_valid_days() {
+ echo
+ while :
+ do
+ echo -en "Minimum days between password changes: [${def_pwd_min}] "
+ read min_days
+
+ if test -z "${min_days}"
+ then
+ min_days="${def_pwd_min}"
+ echo "Using ${min_days}"
+ return
+ fi
+
+ if ! expr "${min_days}" : '^[0-9]+$' &> /dev/null
+ then
+ echo "Please use numbers only."
+ continue
+ fi
+ if test "${min_days}" -gt 7
+ then
+ echo "Warning: you are using a value longer than a week."
+ fi
+
+ def_pwd_min="${min_days}"
+ return
+ done
+}
+
+read_warning_days() {
+ echo
+ while :
+ do
+ echo -en "Number of warning days before password expires: [${def_pwd_warn}] "
+ read warn_days
+
+ if test -z "${warn_days}"
+ then
+ warn_days="${def_pwd_warn}"
+ echo "Using ${warn_days}"
+ fi
+
+ if ! expr "${warn_days}" : '^[0-9]+$' &> /dev/null
+ then
+ echo "Please use numbers only."
+ continue
+ fi
+ if test "${warn_days}" -gt 14
+ then
+ echo "Warning: you are using a value longer than two week."
+ fi
+
+ def_pwd_warn="${warn_days}"
+ return
+ done
+}
+
+
+read_inactive_days() {
+ echo
+ while :
+ do
+ echo -en "Number of usable days after expiration: [${def_pwd_iact}] "
+ read iact_days
+
+ if test -z "${iact_days}"
+ then
+ iact_days="${def_pwd_iact}"
+ echo "Using ${iact_days}"
+ return
+ fi
+ if ! expr "${iact_days}" : '^[0-9]+$' &> /dev/null
+ then
+ echo "Please use numbers only."
+ continue
+ fi
+ if test "${iact_days}" -gt 14
+ then
+ echo "Warning: you are using a value that is more than two weeks."
+ fi
+
+ def_pwd_iact="${iact_days}"
+ return
+ done
+}
+
+read_expire_date() {
+ local ans
+
+ echo
+ while :
+ do
+ echo -en "Expire date of this account (mm/dd/yy): [${def_expire:-never}] "
+ read ans
+
+ if test -z "${ans}"
+ then
+ if test -z "${def_expire}"
+ then
+ ans="never"
+ else
+ ans="${def_expire}"
+ echo "Using ${def_expire}"
+ fi
+ fi
+
+ if test "${ans}" = "never"
+ then
+ echo "Account will never expire."
+ def_expire=""
+ expire=""
+ return
+ fi
+
+ if ! expr "${ans}" : '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]$' &> /dev/null
+ then
+ echo "Please use format mm/dd/yy"
+ continue
+ fi
+
+ if ! expire_date="$(date -d ${ans} '+%A, %B %d %Y')"
+ then
+ continue
+ fi
+
+ def_expire="${expire}"
+ return
+ done
+}
+
+read_passwd_yn() {
+ echo -en "\nDo you want to set password [Y/n] ? "
+ if read_yn 0
+ then
+ set_pwd="YES"
+ else
+ set_pwd=""
+ fi
+}
+
+
+print_values() {
+
+clear
+cat << EOM
+
+Login: ${S}${login}${E}
+Group: ${S}${group}${E}
+Other groups: ${S}${other_groups:-[none]}${E}
+
+Real Name: ${S}${name}${E}
+
+uid: ${S}${uid:-[first free]}${E}
+home: ${S}${home}${E}
+shell: ${S}${shell}${E}
+
+Account expiration date: ${S}${expire_date:-never}${E}
+Minimum days between password changes: ${S}${min_days}${E}
+Maximum days between password changes: ${S}${max_days}${E}
+Number of usable days after expiration: ${S}${iact_days}${E}
+Number of warning days before expiration: ${S}${warn_days}${E}
+
+${S}${set_pwd:+Set password for this account.}${E}
+
+EOM
+}
+
+set_user() {
+ if ! useradd \
+ -c "${name}" \
+ -d "${home}" \
+ -g "${group}" \
+ -s "${shell}" \
+ ${expire:+-e ${expire}} \
+ ${uid:+-u ${uid}} \
+ ${other_groups:+-G ${other_groups}} \
+ ${login}
+ then
+ echo "Error ($?) in useradd...exiting..."
+ exit 1
+ fi
+}
+
+set_aging() {
+ if ! passwd \
+ -x ${max_days} \
+ -n ${min_days} \
+ -w ${warn_days} \
+ -i ${iact_days} \
+ ${login}
+ then
+ echo "Error ($?) in setting password aging...exiting..."
+ exit 1
+ fi
+}
+
+set_password() {
+ if test -n "${set_pwd}"
+ then
+ echo
+ passwd ${login}
+ echo
+ fi
+}
+
+set_system() {
+ if test -d "${home}"
+ then
+ echo "Directory ${home} already exists."
+ echo "Skeleton files not copied."
+ return
+ fi
+
+ echo -n "Copying skeleton files..."
+ (
+ mkdir ${home}
+ cd ${skel} && cp -af . ${home}
+ chmod ${def_mode} ${home}
+ chown -R ${login}:${group} ${home}
+ )
+ echo "done."
+
+ ## Add your own stuff here:
+ echo -n "Setting up other files..."
+ (
+ mailbox="/var/spool/mail/${login}"
+ touch ${mailbox}
+ chown "${login}:mail" ${mailbox}
+ chmod 600 ${mailbox}
+ )
+ echo "done."
+}
+
+
+read_values() {
+ clear
+ echo -e "\nPlease answer the following questions about the new user to be added."
+
+ while :
+ do
+ read_login
+ read_name
+ read_group
+ read_other_groups
+ read_home
+ read_shell
+ read_uid
+ read_expire_date
+ read_max_valid_days
+ read_min_valid_days
+ read_warning_days
+ read_inactive_days
+ read_passwd_yn
+
+ print_values
+
+ echo -n "Is this correct [N/y] ? "
+ read_yn 1 && return
+ done
+}
+
+
+main() {
+ check_root
+ read_values
+ set_user
+ set_aging
+ set_system
+ set_password
+}
+
+
+## Run it 8-)
+main
+
+# End.
diff --git a/current/contrib/atudel b/current/contrib/atudel
new file mode 100755
index 00000000..0ca87833
--- /dev/null
+++ b/current/contrib/atudel
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 1996 Brian R. Gaeke
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by Brian R. Gaeke.
+# 4. The name of the author, Brian R. Gaeke, may not be used to endorse
+# or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY BRIAN R. GAEKE ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL BRIAN R. GAEKE BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Additionally:
+#
+# This software is provided without support and without any obligation
+# on the part of Brian R. Gaeke to assist in its use, correction,
+# modification or enhancement.
+#
+#######################################################################
+#
+# this is atudel, version 2, by Brian R. Gaeke <brg@dgate.org>
+#
+
+require "getopts.pl";
+&Getopts('v');
+$username = shift(@ARGV);
+&usage unless $username;
+
+sub usage
+{
+ print STDERR "atudel - remove all at jobs owned by a user\n";
+ print STDERR "usage: $0 [-v] username\n";
+ exit(1);
+}
+
+# odd. unless getpwnam($uname) doesn't seem to work for $uname eq "root" on
+# my linux system. but this does.
+die "user $username does not exist; stopping"
+ unless defined(getpwnam($username));
+
+print "searching for at jobs owned by user $username ..." if $opt_v;
+
+chdir "/var/spool/atjobs" ||
+ die "can't chdir to /var/spool/atjobs: $!\nstopping";
+opendir(DIR,".") || die "can't opendir(/var/spool/atjobs): $!\nstopping";
+@files = grep(!/^\./,grep(-f,readdir(DIR)));
+closedir DIR;
+
+foreach $x (@files)
+{
+ $owner = (getpwuid((stat($x))[4]))[0];
+ push(@nuke_bait,$x) if $owner eq $username;
+}
+
+if (@nuke_bait)
+{
+ print "removed jobIDs: @{nuke_bait}.\n" if $opt_v;
+ unlink @nuke_bait;
+}
+elsif ($opt_v)
+{
+ print "\n";
+}
+
+exit 0;
diff --git a/current/contrib/groupmems.shar b/current/contrib/groupmems.shar
new file mode 100644
index 00000000..d45efd2e
--- /dev/null
+++ b/current/contrib/groupmems.shar
@@ -0,0 +1,546 @@
+#!/bin/sh
+# This is a shell archive (produced by GNU sharutils 4.2.1).
+# To extract the files from this archive, save it to some FILE, remove
+# everything before the `!/bin/sh' line above, then type `sh FILE'.
+#
+# Made on 2000-05-25 14:41 CDT by <gk4@gnu.austin.ibm.com>.
+# Source directory was `/home/gk4/src/groupmem'.
+#
+# Existing files will *not* be overwritten unless `-c' is specified.
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 1960 -rw-r--r-- Makefile
+# 6348 -rw-r--r-- groupmems.c
+# 3372 -rw------- groupmems.8
+#
+save_IFS="${IFS}"
+IFS="${IFS}:"
+gettext_dir=FAILED
+locale_dir=FAILED
+first_param="$1"
+for dir in $PATH
+do
+ if test "$gettext_dir" = FAILED && test -f $dir/gettext \
+ && ($dir/gettext --version >/dev/null 2>&1)
+ then
+ set `$dir/gettext --version 2>&1`
+ if test "$3" = GNU
+ then
+ gettext_dir=$dir
+ fi
+ fi
+ if test "$locale_dir" = FAILED && test -f $dir/shar \
+ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
+ then
+ locale_dir=`$dir/shar --print-text-domain-dir`
+ fi
+done
+IFS="$save_IFS"
+if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
+then
+ echo=echo
+else
+ TEXTDOMAINDIR=$locale_dir
+ export TEXTDOMAINDIR
+ TEXTDOMAIN=sharutils
+ export TEXTDOMAIN
+ echo="$gettext_dir/gettext -s"
+fi
+if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
+ shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
+elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
+ shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
+elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
+ shar_touch='touch -am $3$4$5$6$2 "$8"'
+else
+ shar_touch=:
+ echo
+ $echo 'WARNING: not restoring timestamps. Consider getting and'
+ $echo "installing GNU \`touch', distributed in GNU File Utilities..."
+ echo
+fi
+rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
+#
+if mkdir _sh10937; then
+ $echo 'x -' 'creating lock directory'
+else
+ $echo 'failed to create lock directory'
+ exit 1
+fi
+# ============= Makefile ==============
+if test -f 'Makefile' && test "$first_param" != -c; then
+ $echo 'x -' SKIPPING 'Makefile' '(file already exists)'
+else
+ $echo 'x -' extracting 'Makefile' '(text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
+/*
+# Copyright 2000, International Business Machines, Inc.
+# All rights reserved.
+#
+# original author: George Kraft IV, gk4@us.ibm.com
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of International Business Machines, Inc., nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+X
+all: groupmems
+X
+groupmems: groupmems.c
+X cc -g -o groupmems groupmems.c -L. -lshadow
+X
+install: groupmems
+X -/usr/sbin/groupadd groups
+X install -o root -g groups -m 4770 groupmems /usr/bin
+X
+install.man: groupmems.8
+X install -o root -g root -m 644 groupmems.8 /usr/man/man8
+X
+SHAR_EOF
+ (set 20 00 05 25 14 40 28 'Makefile'; eval "$shar_touch") &&
+ chmod 0644 'Makefile' ||
+ $echo 'restore of' 'Makefile' 'failed'
+ if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+ md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+ || $echo 'Makefile:' 'MD5 check failed'
+b46cf7ef8d59149093c011ced3f3103c Makefile
+SHAR_EOF
+ else
+ shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
+ test 1960 -eq "$shar_count" ||
+ $echo 'Makefile:' 'original size' '1960,' 'current size' "$shar_count!"
+ fi
+fi
+# ============= groupmems.c ==============
+if test -f 'groupmems.c' && test "$first_param" != -c; then
+ $echo 'x -' SKIPPING 'groupmems.c' '(file already exists)'
+else
+ $echo 'x -' extracting 'groupmems.c' '(text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' &&
+/*
+X * Copyright 2000, International Business Machines, Inc.
+X * All rights reserved.
+X *
+X * original author: George Kraft IV, gk4@us.ibm.com
+X *
+X * Redistribution and use in source and binary forms, with or without
+X * modification, are permitted provided that the following conditions
+X * are met:
+X *
+X * 1. Redistributions of source code must retain the above copyright
+X * notice, this list of conditions and the following disclaimer.
+X * 2. Redistributions in binary form must reproduce the above copyright
+X * notice, this list of conditions and the following disclaimer in the
+X * documentation and/or other materials provided with the distribution.
+X * 3. Neither the name of International Business Machines, Inc., nor the
+X * names of its contributors may be used to endorse or promote products
+X * derived from this software without specific prior written permission.
+X *
+X * THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
+X * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+X * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+X * INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
+X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+X * SUCH DAMAGE.
+X */
+/*
+**
+** Utility "groupmem" adds and deletes members from a user's group.
+**
+** Setup (as "root"):
+**
+** groupadd -r groups
+** chmod 2770 groupmems
+** chown root.groups groupmems
+** groupmems -g groups -a gk4
+**
+** Usage (as "gk4"):
+**
+** groupmems -a olive
+** groupmems -a jordan
+** groupmems -a meghan
+** groupmems -a morgan
+** groupmems -a jake
+** groupmems -l
+** groupmems -d jake
+** groupmems -l
+*/
+X
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "defines.h"
+#include "groupio.h"
+X
+/* Exit Status Values */
+X
+#define EXIT_SUCCESS 0 /* success */
+#define EXIT_USAGE 1 /* invalid command syntax */
+#define EXIT_GROUP_FILE 2 /* group file access problems */
+#define EXIT_NOT_ROOT 3 /* not super user */
+#define EXIT_NOT_EROOT 4 /* not effective super user */
+#define EXIT_NOT_PRIMARY 5 /* not primary owner of group */
+#define EXIT_NOT_MEMBER 6 /* member of group does not exist */
+#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */
+X
+#define TRUE 1
+#define FALSE 0
+X
+/* Globals */
+X
+extern int optind;
+extern char *optarg;
+static char *adduser = NULL;
+static char *deluser = NULL;
+static char *thisgroup = NULL;
+static int purge = FALSE;
+static int list = FALSE;
+static int exclusive = 0;
+X
+static int isroot(void) {
+X return getuid() ? FALSE : TRUE;
+}
+X
+static int isgroup(void) {
+X gid_t g = getgid();
+X struct group *grp = getgrgid(g);
+X
+X return TRUE;
+}
+X
+static char *whoami(void) {
+X struct group *grp = getgrgid(getgid());
+X struct passwd *usr = getpwuid(getuid());
+X
+X if (0 == strcmp(usr->pw_name, grp->gr_name)) {
+X return (char *)strdup(usr->pw_name);
+X } else {
+X return NULL;
+X }
+}
+X
+static void
+addtogroup(char *user, char **members) {
+X int i;
+X char **pmembers;
+X
+X for (i = 0; NULL != members[i]; i++ ) {
+X if (0 == strcmp(user, members[i])) {
+X fprintf(stderr, "Member already exists\n");
+X exit(EXIT_MEMBER_EXISTS);
+X }
+X }
+X
+X if (0 == i) {
+X pmembers = (char **)calloc(2, sizeof(char *));
+X } else {
+X pmembers = (char **)realloc(members, sizeof(char *)*(i+1));
+X }
+X
+X *members = *pmembers;
+X members[i] = user;
+X members[i+1] = NULL;
+}
+X
+static void
+rmfromgroup(char *user, char **members) {
+X int i;
+X int found = FALSE;
+X
+X i = 0;
+X while (!found && NULL != members[i]) {
+X if (0 == strcmp(user, members[i])) {
+X found = TRUE;
+X } else {
+X i++;
+X }
+X }
+X
+X while (found && NULL != members[i]) {
+X members[i] = members[++i];
+X }
+X
+X if (!found) {
+X fprintf(stderr, "Member to remove could not be found\n");
+X exit(EXIT_NOT_MEMBER);
+X }
+}
+X
+static void
+nomembers(char **members) {
+X int i;
+X
+X for (i = 0; NULL != members[i]; i++ ) {
+X members[i] = NULL;
+X }
+}
+X
+static void
+members(char **members) {
+X int i;
+X
+X for (i = 0; NULL != members[i]; i++ ) {
+X printf("%s ", members[i]);
+X
+X if (NULL == members[i+1]) {
+X printf("\n");
+X } else {
+X printf(" ");
+X }
+X }
+}
+X
+static void usage(void) {
+X fprintf(stderr, "usage: groupmems -a username | -d username | -D | -l [-g groupname]\n");
+X exit(EXIT_USAGE);
+}
+X
+main(int argc, char **argv) {
+X int arg, i;
+X char *name;
+X struct group *grp;
+X
+X while ((arg = getopt(argc, argv, "a:d:g:Dl")) != EOF) {
+X switch (arg) {
+X case 'a':
+X adduser = strdup(optarg);
+X ++exclusive;
+X break;
+X case 'd':
+X deluser = strdup(optarg);
+X ++exclusive;
+X break;
+X case 'g':
+X thisgroup = strdup(optarg);
+X break;
+X case 'D':
+X purge = TRUE;
+X ++exclusive;
+X break;
+X case 'l':
+X list = TRUE;
+X ++exclusive;
+X break;
+X default:
+X usage();
+X }
+X }
+X
+X if (exclusive > 1 || optind < argc) {
+X usage();
+X }
+X
+X if (!isroot() && NULL != thisgroup) {
+X fprintf(stderr, "Only root can add members to different groups\n");
+X exit(EXIT_NOT_ROOT);
+X } else if (isroot() && NULL != thisgroup) {
+X name = thisgroup;
+X } else if (!isgroup()) {
+X fprintf(stderr, "Group access is required\n");
+X exit(EXIT_NOT_EROOT);
+X } else if (NULL == (name = whoami())) {
+X fprintf(stderr, "Not primary owner of current group\n");
+X exit(EXIT_NOT_PRIMARY);
+X }
+X
+X if (!gr_lock()) {
+X fprintf(stderr, "Unable to lock group file\n");
+X exit(EXIT_GROUP_FILE);
+X }
+X
+X if (!gr_open(O_RDWR)) {
+X fprintf(stderr, "Unable to open group file\n");
+X exit(EXIT_GROUP_FILE);
+X }
+X
+X grp = (struct group *)gr_locate(name);
+X
+X if (NULL != adduser) {
+X addtogroup(adduser, grp->gr_mem);
+X gr_update(grp);
+X } else if (NULL != deluser) {
+X rmfromgroup(deluser, grp->gr_mem);
+X gr_update(grp);
+X } else if (purge) {
+X nomembers(grp->gr_mem);
+X gr_update(grp);
+X } else if (list) {
+X members(grp->gr_mem);
+X }
+X
+X if (!gr_close()) {
+X fprintf(stderr, "Cannot close group file\n");
+X exit(EXIT_GROUP_FILE);
+X }
+X
+X gr_unlock();
+X
+X exit(EXIT_SUCCESS);
+}
+X
+/* EOF */
+SHAR_EOF
+ (set 20 00 05 25 14 36 38 'groupmems.c'; eval "$shar_touch") &&
+ chmod 0644 'groupmems.c' ||
+ $echo 'restore of' 'groupmems.c' 'failed'
+ if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+ md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+ || $echo 'groupmems.c:' 'MD5 check failed'
+f0dd68f8d762d89d24d3ce1f4141f981 groupmems.c
+SHAR_EOF
+ else
+ shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.c'`"
+ test 6348 -eq "$shar_count" ||
+ $echo 'groupmems.c:' 'original size' '6348,' 'current size' "$shar_count!"
+ fi
+fi
+# ============= groupmems.8 ==============
+if test -f 'groupmems.8' && test "$first_param" != -c; then
+ $echo 'x -' SKIPPING 'groupmems.8' '(file already exists)'
+else
+ $echo 'x -' extracting 'groupmems.8' '(text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' &&
+X.\"
+X.\" Copyright 2000, International Business Machines, Inc.
+X.\" All rights reserved.
+X.\"
+X.\" original author: George Kraft IV, gk4@us.ibm.com
+X.\"
+X.\" Redistribution and use in source and binary forms, with or without
+X.\" modification, are permitted provided that the following conditions
+X.\" are met:
+X.\"
+X.\" 1. Redistributions of source code must retain the above copyright
+X.\" notice, this list of conditions and the following disclaimer.
+X.\" 2. Redistributions in binary form must reproduce the above copyright
+X.\" notice, this list of conditions and the following disclaimer in the
+X.\" documentation and/or other materials provided with the distribution.
+X.\" 3. Neither the name of International Business Machines, Inc., nor the
+X.\" names of its contributors may be used to endorse or promote products
+X.\" derived from this software without specific prior written permission.
+X.\"
+X.\" THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
+X.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+X.\" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+X.\" INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
+X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+X.\" SUCH DAMAGE.
+X.\"
+X.\" $Id: groupmems.shar,v 1.1 2000/08/26 18:37:32 marekm Exp $
+X.\"
+X.TH GROUPMEMS 8
+X.SH NAME
+groupmems \- Administer members of a user's primary group
+X.SH SYNOPSIS
+X.B groupmems
+\fB-a\fI user_name \fR |
+\fB-d\fI user_name \fR |
+\fB-l\fR |
+\fB-D\fR |
+[\fB-g\fI group_name \fR]
+X.SH DESCRIPTION
+The \fBgroupmems\fR utility allows a user to administer his/her own
+group membership list without the requirement of super user privileges.
+The \fBgroupmems\fR utility is for systems that configure its users to
+be in their own name sake primary group (i.e., guest / guest).
+X.P
+Only the super user, as administrator, can use \fBgroupmems\fR to alter
+the memberships of other groups.
+X.IP "\fB-a \fIuser_name\fR"
+Add a new user to the group membership list.
+X.IP "\fB-d \fIuser_name\fR"
+Delete a user from the group membership list.
+X.IP "\fB-l\fR"
+List the group membership list.
+X.IP "\fB-D\fR"
+Delete all users from the group membership list.
+X.IP "\fB-g \fIgroup_name\fR"
+The super user can specify which group membership list to modify.
+X.SH SETUP
+The \fBgroupmems\fR executable should be in mode \fB2770\fR as user \fBroot\fR
+and in group \fBgroups\fR. The system administrator can add users to
+group groups to allow or disallow them using the \fBgroupmems\fR utility
+to manager their own group membership list.
+X.P
+X $ groupadd -r groups
+X.br
+X $ chmod 2770 groupmems
+X.br
+X $ chown root.groups groupmems
+X.br
+X $ groupmems -g groups -a gk4
+X.SH FILES
+/etc/group
+X.br
+/etc/gshadow
+X.SH SEE ALSO
+X.BR chfn (1),
+X.BR chsh (1),
+X.BR useradd (8),
+X.BR userdel (8),
+X.BR usermod (8),
+X.BR passwd (1),
+X.BR groupadd (8),
+X.BR groupdel (8)
+X.SH AUTHOR
+George Kraft IV (gk4@us.ibm.com)
+X.\" EOF
+SHAR_EOF
+ (set 20 00 05 25 14 38 23 'groupmems.8'; eval "$shar_touch") &&
+ chmod 0600 'groupmems.8' ||
+ $echo 'restore of' 'groupmems.8' 'failed'
+ if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
+ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
+ md5sum -c << SHAR_EOF >/dev/null 2>&1 \
+ || $echo 'groupmems.8:' 'MD5 check failed'
+181e6cd3a3c9d3df320197fa2cde2b4a groupmems.8
+SHAR_EOF
+ else
+ shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.8'`"
+ test 3372 -eq "$shar_count" ||
+ $echo 'groupmems.8:' 'original size' '3372,' 'current size' "$shar_count!"
+ fi
+fi
+rm -fr _sh10937
+exit 0
diff --git a/current/contrib/pwdauth.c b/current/contrib/pwdauth.c
new file mode 100644
index 00000000..1bedf6bb
--- /dev/null
+++ b/current/contrib/pwdauth.c
@@ -0,0 +1,308 @@
+/*
+ * pwdauth.c - program to verify a given username/password pair.
+ *
+ * Run it with username in argv[1] (may be omitted - default is the
+ * current user), and send it the password over a pipe on stdin.
+ * Exit status: 0 - correct password, 1 - wrong password, >1 - other
+ * errors. For use with shadow passwords, this program should be
+ * installed setuid root.
+ *
+ * This can be used, for example, by xlock - you don't have to install
+ * this large and complex (== possibly insecure) program setuid root,
+ * just modify it to run this simple program to do the authentication.
+ *
+ * Recent versions (xlockmore-3.9) are cleaner, and drop privileges as
+ * soon as possible after getting the user's encrypted password.
+ * Using this program probably doesn't make it more secure, and has one
+ * disadvantage: since we don't get the encrypted user's password at
+ * startup (but at the time the user is authenticated), it is not clear
+ * how we should handle errors (like getpwnam() returning NULL).
+ * - fail the authentication? Problem: no way to unlock (other than kill
+ * the process from somewhere else) if the NIS server stops responding.
+ * - succeed and unlock? Problem: it's too easy to unlock by unplugging
+ * the box from the network and waiting until NIS times out...
+ *
+ * This program is Copyright (C) 1996 Marek Michalkiewicz
+ * <marekm@i17linuxb.ists.pwr.wroc.pl>.
+ *
+ * It may be used and distributed freely for any purposes. There is no
+ * warranty - use at your own risk. I am not liable for any damages etc.
+ * If you improve it, please send me your changes.
+ */
+
+static char rcsid[] = "$Id: pwdauth.c,v 1.2 1997/12/07 23:26:45 marekm Exp $";
+
+/*
+ * Define USE_SYSLOG to use syslog() to log successful and failed
+ * authentication. This should be safe even if your system has
+ * the infamous syslog buffer overrun security problem...
+ */
+#define USE_SYSLOG
+
+/*
+ * Define HAVE_GETSPNAM to get shadow passwords using getspnam().
+ * Some systems don't have getspnam(), but getpwnam() returns
+ * encrypted passwords only if running as root.
+ *
+ * According to the xlock source (not tested, except Linux) -
+ * define: Linux, Solaris 2.x, SVR4, ...
+ * undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX.
+ * Known not supported (yet): Ultrix, OSF/1, SCO.
+ */
+#define HAVE_GETSPNAM
+
+/*
+ * Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt().
+ * pw_encrypt() is like the standard crypt(), except that it may
+ * support better password hashing algorithms.
+ *
+ * Define if linking with libshadow.a from the shadow password
+ * suite (Linux, SunOS 4.x?).
+ */
+#undef HAVE_PW_ENCRYPT
+
+/*
+ * Define HAVE_AUTH_METHODS to support the shadow suite specific
+ * extension: the encrypted password field contains a list of
+ * administrator defined authentication methods, separated by
+ * semicolons. This program only supports the standard password
+ * authentication method (a string that doesn't start with '@').
+ */
+#undef HAVE_AUTH_METHODS
+
+/*
+ * FAIL_DELAY - number of seconds to sleep before exiting if the
+ * password was wrong, to slow down password guessing attempts.
+ */
+#define FAIL_DELAY 2
+
+/* No user-serviceable parts below :-). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#ifdef USE_SYSLOG
+#include <syslog.h>
+#ifndef LOG_AUTHPRIV
+#define LOG_AUTHPRIV LOG_AUTH
+#endif
+#endif
+
+#ifdef HAVE_GETSPNAM
+#include <shadow.h>
+#endif
+
+#ifdef HAVE_PW_ENCRYPT
+extern char *pw_encrypt();
+#define crypt pw_encrypt
+#endif
+
+/*
+ * Read the password (one line) from fp. We don't turn off echo
+ * because we expect input from a pipe.
+ */
+static char *
+get_line(fp)
+ FILE *fp;
+{
+ static char buf[128];
+ char *cp;
+ int ch;
+
+ cp = buf;
+ while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') {
+ if (cp >= buf + sizeof buf - 1)
+ break;
+ *cp++ = ch;
+ }
+ *cp = '\0';
+ return buf;
+}
+
+/*
+ * Get the password file entry for the current user. If the name
+ * returned by getlogin() is correct (matches the current real uid),
+ * return the entry for that user. Otherwise, return the entry (if
+ * any) matching the current real uid. Return NULL on failure.
+ */
+static struct passwd *
+get_my_pwent()
+{
+ uid_t uid = getuid();
+ char *name = getlogin();
+
+ if (name && *name) {
+ struct passwd *pw = getpwnam(name);
+
+ if (pw && pw->pw_uid == uid)
+ return pw;
+ }
+ return getpwuid(uid);
+}
+
+/*
+ * Verify the password. The system-dependent shadow support is here.
+ */
+static int
+password_auth_ok(pw, pass)
+ const struct passwd *pw;
+ const char *pass;
+{
+ int result;
+ char *cp;
+#ifdef HAVE_AUTH_METHODS
+ char *buf;
+#endif
+#ifdef HAVE_GETSPNAM
+ struct spwd *sp;
+#endif
+
+ if (pw) {
+#ifdef HAVE_GETSPNAM
+ sp = getspnam(pw->pw_name);
+ if (sp)
+ cp = sp->sp_pwdp;
+ else
+#endif
+ cp = pw->pw_passwd;
+ } else
+ cp = "xx";
+
+#ifdef HAVE_AUTH_METHODS
+ buf = strdup(cp); /* will be modified by strtok() */
+ if (!buf) {
+ fprintf(stderr, "Out of memory.\n");
+ exit(13);
+ }
+ cp = strtok(buf, ";");
+ while (cp && *cp == '@')
+ cp = strtok(NULL, ";");
+
+ /* fail if no password authentication for this user */
+ if (!cp)
+ cp = "xx";
+#endif
+
+ if (*pass || *cp)
+ result = (strcmp(crypt(pass, cp), cp) == 0);
+ else
+ result = 1; /* user with no password */
+
+#ifdef HAVE_AUTH_METHODS
+ free(buf);
+#endif
+ return result;
+}
+
+/*
+ * Main program.
+ */
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct passwd *pw;
+ char *pass, *name;
+ char myname[32];
+
+#ifdef USE_SYSLOG
+ openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
+#endif
+ pw = get_my_pwent();
+ if (!pw) {
+#ifdef USE_SYSLOG
+ syslog(LOG_ERR, "can't get login name for uid %d.\n",
+ (int) getuid());
+#endif
+ fprintf(stderr, "Who are you?\n");
+ exit(2);
+ }
+ strncpy(myname, pw->pw_name, sizeof myname - 1);
+ myname[sizeof myname - 1] = '\0';
+ name = myname;
+
+ if (argc > 1) {
+ name = argv[1];
+ pw = getpwnam(name);
+ }
+
+ pass = get_line(stdin);
+ if (password_auth_ok(pw, pass)) {
+#ifdef USE_SYSLOG
+ syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE,
+ "user `%s' entered correct password for `%.32s'.\n",
+ myname, name);
+#endif
+ exit(0);
+ }
+#ifdef USE_SYSLOG
+ /* be careful not to overrun the syslog buffer */
+ syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING,
+ "user `%s' entered incorrect password for `%.32s'.\n",
+ myname, name);
+#endif
+#ifdef FAIL_DELAY
+ sleep(FAIL_DELAY);
+#endif
+ fprintf(stderr, "Wrong password.\n");
+ exit(1);
+}
+
+#if 0
+/*
+ * You can use code similar to the following to run this program.
+ * Return values: >=0 - program exit status (use the <sys/wait.h>
+ * macros to get the exit code, it is shifted left by 8 bits),
+ * -1 - check errno.
+ */
+int
+verify_password(const char *username, const char *password)
+{
+ int pipe_fd[2];
+ int pid, wpid, status;
+
+ if (pipe(pipe_fd))
+ return -1;
+
+ if ((pid = fork()) == 0) {
+ char *arg[3];
+ char *env[1];
+
+ /* child */
+ close(pipe_fd[1]);
+ if (pipe_fd[0] != 0) {
+ if (dup2(pipe_fd[0], 0) != 0)
+ _exit(127);
+ close(pipe_fd[0]);
+ }
+ arg[0] = "/usr/bin/pwdauth";
+ arg[1] = username;
+ arg[2] = NULL;
+ env[0] = NULL;
+ execve(arg[0], arg, env);
+ _exit(127);
+ } else if (pid == -1) {
+ /* error */
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
+ return -1;
+ }
+ /* parent */
+ close(pipe_fd[0]);
+ write(pipe_fd[1], password, strlen(password));
+ write(pipe_fd[1], "\n", 1);
+ close(pipe_fd[1]);
+
+ while ((wpid = wait(&status)) != pid) {
+ if (wpid == -1)
+ return -1;
+ }
+ return status;
+}
+#endif
diff --git a/current/contrib/rpasswd.c b/current/contrib/rpasswd.c
new file mode 100644
index 00000000..da6b77c0
--- /dev/null
+++ b/current/contrib/rpasswd.c
@@ -0,0 +1,591 @@
+/* rpasswd.c -- restricted `passwd' wrapper.
+ Copyright (C) 1996 Adam Solesby, Joshua Cowan
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This program is meant to be a wrapper for use with `sudo' and your
+ system's `passwd' program. It is *probably* secure, but there is no
+ warranty (see above). If you find errors or security holes, please
+ email me; please include a complete description of the problem in
+ your message in addition to any patches. */
+
+/* This program currently assumes that the arguments given on the
+ command line are user names to pass to the `passwd' program; it loops
+ through the arguments calling `passwd' on each one. It might be
+ better to pass all remaining arguments after `--' to `passwd' (to
+ e.g., change the user's shell instead of the password by giving it
+ the `-s' option). */
+
+/* Written by Adam Solesby <adam@shack.com>. */
+/* Rewritten by Joshua Cowan <jcowan@hermit.reslife.okstate.edu>. */
+
+/* Usage: rpasswd USERNAME...
+ Enforce password-changing guidelines.
+
+ --check[=file] check configuration information; if FILE is given,
+ use that instead of the standard configuration
+ file `./rpasswd.conf'
+ --help display this help and exit
+ --version output version information and exit
+
+ You may never change a superuser's password with this command.
+ Changing certain other users' passwords may also be forbidden; for
+ details of who's passwords may not be changed, try `rpasswd --check'. */
+
+/* TODO:
+
+ - Make this more portable. It currently depends on several
+ GNU/Linux-specific features. */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/* This is the absolute path to the `passwd' program on your system. */
+#define _PATH_PASSWD "/usr/bin/passwd"
+
+/* This is the absolute path to the configuration file. */
+#define _PATH_RPASSWD_CONF "/etc/rpasswd.conf"
+
+/* Don't change the password of any user with a uid equal to or below
+ this number--no matter what the configuration file says. */
+#define UID_PWD_CHANGE_FLOOR 100
+
+/* Everything past this point should probably be left alone. */
+
+/* These are the facility and priority (respectively) used by the syslog
+ functions. */
+#define LOG_FACILITY LOG_AUTH
+#define LOG_PRIORITY LOG_WARNING
+
+/* The name this program was run with. */
+char *program_name;
+
+/* The version information for this program. */
+char *version_string = "1.2";
+
+/* If nonzero, display usage information and exit. */
+static int show_help;
+
+/* If nonzero, print the version on standard output then exit. */
+static int show_version;
+
+/* If nonzero, check the configuration file for errors and print the
+ list of restrictions on the standard output, then exit. */
+static int check_only;
+
+struct user_list
+{
+ char *name;
+ struct user_list *next;
+};
+
+struct config_info
+{
+ /* Don't change the password for any user with a uid less than or
+ equal to this number. */
+ uid_t minimum_uid;
+
+ /* Don't change the password for any user matching this list of user
+ names. */
+ struct user_list *inviolate_user_names;
+};
+
+static const struct option long_options[] =
+{
+ {"check", optional_argument, 0, 10},
+ {"version", no_argument, &show_version, 1},
+ {"help", no_argument, &show_help, 1},
+ {0, 0, 0, 0}
+};
+
+static struct config_info *get_config_info ();
+static int dump_config_info ();
+static void *xmalloc ();
+static void *xrealloc ();
+static void xsyslog (int, const char *, ...);
+static void dal_error (int, int, const char *, ...);
+
+static void
+usage (status)
+ int status;
+{
+ if (status != 0)
+ fprintf (stderr, "Try `%s --help' for more information.\n",
+ program_name);
+ else
+ {
+ printf ("Usage: %s USERNAME...\n", program_name);
+ fputs ("\
+Enforce password-changing guidelines.\n\
+\n\
+ --check[=file] check configuration information; if FILE is given,\n\
+ use that instead of the standard configuration file\n\
+ `"_PATH_RPASSWD_CONF"'\n\
+ --help display this help and exit\n\
+ --version output version information and exit\n",
+ stdout);
+
+ printf ("\n\
+You may never change a superuser's password with this command. Changing\n\
+certain other users' passwords may also be forbidden; for details of\n\
+who's passwords may not be changed, try `%s --check'.\n",
+ program_name);
+ }
+
+ exit (status);
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *executing_user_name;
+ char *config_file_name = _PATH_RPASSWD_CONF;
+ int opt;
+ struct config_info *config;
+
+ /* Setting values of global variables. */
+ program_name = argv[0];
+
+ while ((opt = getopt_long (argc, argv, "", long_options, 0))
+ != EOF)
+ switch (opt)
+ {
+ case 0:
+ break;
+
+ case 10:
+ check_only = 1;
+ if (optarg)
+ config_file_name = optarg;
+ break;
+
+ default:
+ usage (1);
+ }
+
+ if (show_version)
+ {
+ printf ("rpasswd %s\n", version_string);
+ return 0;
+ }
+
+ if (show_help)
+ {
+ usage (0);
+ }
+
+ if (check_only)
+ {
+ dump_config_info (config_file_name);
+ exit (0);
+ }
+
+ if (optind >= argc)
+ {
+ fprintf (stderr, "%s: missing argument\n", program_name);
+ usage (1);
+ }
+
+ /* FIXME: does `sudo' set the real user id to the effective user id?
+ If so, this won't work as intended: We want to get the name of the
+ user who ran `sudo'. I am reluctant to use `getlogin' for obvious
+ reasons, but it may be better than nothing. Maybe someone who
+ actually has `sudo' installed can tell me if this works, or how to
+ fix it if it doesn't. --JC */
+ do
+ {
+ struct passwd *pwd;
+ uid_t uid = getuid ();
+
+ pwd = getpwuid (uid);
+
+ if (!pwd || !pwd->pw_name)
+ {
+ xsyslog (LOG_PRIORITY,
+ "Unknown user (uid #%d) attempted to change password for `%s'.",
+ uid, argv[optind]);
+ fprintf (stderr, "%s: you do not exist, go away\n",
+ program_name);
+ exit (1);
+ }
+ else
+ executing_user_name = pwd->pw_name;
+ }
+ while (0);
+
+ config = get_config_info (config_file_name);
+
+ for (; optind < argc; optind++)
+ {
+ int immutable_p = 0;
+ struct user_list *user_names = config->inviolate_user_names;
+
+ /* Make sure we weren't given an illegal user name. */
+ for (; user_names; user_names = user_names->next)
+ {
+ if (strcmp (argv[optind], user_names->name)
+ == 0)
+ {
+ immutable_p = 1;
+ break;
+ }
+ }
+
+ if (!immutable_p)
+ {
+ struct passwd *pwd;
+
+ pwd = getpwnam (argv[optind]);
+
+ if (!pwd)
+ {
+ fprintf (stderr, "%s: invalid user `%s'\n",
+ program_name, argv[optind]);
+
+ continue;
+ }
+ else if (pwd->pw_uid <= config->minimum_uid)
+ immutable_p = 1;
+ }
+
+ if (immutable_p)
+ {
+ xsyslog (LOG_PRIORITY,
+ "`%s' attempted to change password for `%s'.",
+ executing_user_name, argv[optind]);
+ fprintf (stderr,
+ "You are not allowed to change the password for `%s'.\n",
+ argv[optind]);
+ }
+ else
+ {
+ int pid, status;
+
+ pid = fork ();
+ switch (pid)
+ {
+ case -1:
+ dal_error (1, errno, "cannot fork");
+
+ case 0:
+ execl (_PATH_PASSWD, _PATH_PASSWD, "--", argv[optind], 0);
+ _exit (1);
+
+ default:
+ while (wait (&status) != pid)
+ ;
+
+ if (status & 0xFFFF)
+ dal_error (1, EIO, "%s", _PATH_PASSWD);
+
+ break;
+ }
+ }
+ }
+
+ exit (0);
+}
+
+/* Get configuration information from FILE and return a pointer to a
+ `config_info' structure containing that information. It currently
+ does minimal checking of the validity of the information.
+
+ This function never returns NULL, even when the configuration file is
+ empty. If the configuration file doesn't exist, it just exits with a
+ failed exit status. */
+
+static struct config_info *
+get_config_info (file)
+ const char *const file;
+{
+ FILE *config_file;
+ struct config_info *config;
+ char linebuf[BUFSIZ];
+ unsigned int lineno = 0;
+
+ config = (struct config_info *) xmalloc (sizeof (struct config_info));
+ config->minimum_uid = (uid_t) 0;
+ config->inviolate_user_names = 0;
+
+ config_file = fopen (file, "r");
+ if (!config_file)
+ dal_error (1, errno, "%s", file);
+
+ if (fseek (config_file, 0L, SEEK_SET))
+ dal_error (1, errno, "%s", file);
+
+ while (fgets (linebuf, BUFSIZ, config_file))
+ {
+ int len, i, uid_found = 0;
+
+ lineno++;
+
+ len = strlen (linebuf);
+
+ /* Chomp any whitespace off the end of the line. */
+ while (isspace (linebuf[len - 1]))
+ linebuf[--len] = '\0';
+
+ /* If this line is empty or a comment, skip it and go to the next. */
+ if (len == 0 || *linebuf == '#')
+ continue;
+
+ for (i = 0; i < len; i++)
+ if (!isalnum (linebuf[i])
+ && linebuf[i] != '.'
+ && linebuf[i] != '-'
+ && linebuf[i] != '_')
+ {
+ dal_error (1, 0, "%s:%u: invalid user name `%s'",
+ file, lineno, linebuf);
+ }
+
+ /* Only accept positive integers as candidates for `minimum_uid'. */
+ for (i = 0; i < len; i++)
+ if (!isdigit (linebuf[i]))
+ break;
+
+ if (!uid_found && i == len)
+ {
+ unsigned long num;
+
+ errno = 0;
+ num = strtoul (linebuf, 0, 10);
+ config->minimum_uid = (uid_t) num;
+
+ if (errno || config->minimum_uid != num)
+ dal_error (1, 0, "%s:%u: `%s' out of range",
+ file, lineno, linebuf);
+
+ uid_found = 1;
+ }
+ else
+ {
+ struct user_list *tail = config->inviolate_user_names;
+ struct user_list *user_names = 0;
+
+ /* This could be more efficient, but makes the list of users
+ printed out with the `--check' switch easier to read. */
+
+ for (; tail; tail = tail->next)
+ {
+ if (strcmp (linebuf, tail->name) == 0)
+ break;
+
+ user_names = tail;
+ }
+
+ if (!tail)
+ {
+ tail = user_names;
+
+ user_names = xmalloc (sizeof (struct user_list));
+ user_names->name = strcpy (xmalloc (len + 1), linebuf);
+ user_names->next = 0;
+
+ if (!config->inviolate_user_names)
+ config->inviolate_user_names = user_names;
+ else
+ tail->next = user_names;
+ }
+ }
+ }
+
+ fclose (config_file);
+
+ if (config->minimum_uid < UID_PWD_CHANGE_FLOOR)
+ config->minimum_uid = UID_PWD_CHANGE_FLOOR;
+
+ return config;
+}
+
+/* Dump the configuration info contained in FILE to the standard output. */
+
+static int
+dump_config_info (file)
+ char *file;
+{
+ struct config_info *config;
+
+ config = get_config_info (file);
+
+ printf ("\
+The lowest uid who's password may be changed is number %d. Changing
+the following users' passwords is also forbidden:\n",
+ config->minimum_uid + 1);
+
+ if (!config->inviolate_user_names)
+ {
+ printf ("\n (no users listed in configuration file `%s')\n",
+ file);
+ }
+ else
+ {
+ int column;
+ struct user_list *user_names = config->inviolate_user_names;
+
+ for (column = 73; user_names; user_names = user_names->next)
+ {
+ int name_len = strlen (user_names->name);
+
+ if (user_names->next)
+ name_len++;
+
+ column += name_len;
+
+ if (column > 72)
+ {
+ fputs ("\n ", stdout);
+ column = name_len + 2;
+ }
+ else if (column - name_len > 0)
+ {
+ fputc (' ', stdout);
+ column++;
+ }
+
+ fputs (user_names->name, stdout);
+
+ if (user_names->next)
+ fputc (',', stdout);
+ }
+
+ fputc ('\n', stdout);
+ }
+
+ return 0;
+}
+
+static void *
+xmalloc (n)
+ size_t n;
+{
+ void *ptr;
+
+ ptr = malloc (n);
+
+ if (!ptr)
+ {
+ fprintf (stderr, "%s: Memory exhausted\n", program_name);
+ exit (1);
+ }
+
+ return ptr;
+}
+
+static void *
+xrealloc (ptr, n)
+ void *ptr;
+ size_t n;
+{
+ ptr = realloc (ptr, n);
+
+ if (!ptr)
+ {
+ fprintf (stderr, "%s: Memory exhausted\n", program_name);
+ exit (1);
+ }
+
+ return ptr;
+}
+
+static void
+xsyslog (int priority, const char *format, ...)
+{
+ va_list args;
+ static int logfd_opened = 0;
+
+ if (!logfd_opened)
+ {
+ openlog (program_name, LOG_PID, LOG_FACILITY);
+ logfd_opened = 1;
+ }
+
+ va_start (args, format);
+ vsyslog (priority, format, args);
+ va_end (args);
+}
+
+/* Format and display MESSAGE on the standard error and send it to the
+ system logger. If ERRNUM is not 0, append the system error message
+ corresponding to ERRNUM to the output. If STATUS is not 0, exit with
+ an exit status of STATUS. */
+
+static void
+dal_error (int status, int errnum, const char *message, ...)
+{
+ va_list args;
+ size_t bufsize;
+ char *formatted_message;
+
+ fflush (stdout);
+
+ bufsize = strlen (message) * 2;
+ formatted_message = (char *) xmalloc (bufsize);
+
+ va_start (args, message);
+
+ while (1)
+ {
+ int printed;
+ printed = vsnprintf (formatted_message, bufsize, message, args);
+
+ if ((size_t) printed < bufsize)
+ break;
+
+ bufsize *= 2;
+ formatted_message = xrealloc (formatted_message, bufsize);
+ }
+
+ va_end (args);
+
+ if (errnum)
+ {
+ char *error_message = strerror (errnum);
+
+ formatted_message
+ = xrealloc (formatted_message,
+ (strlen (formatted_message)
+ + strlen (error_message)
+ + 3));
+
+ strcat (formatted_message, ": ");
+ strcat (formatted_message, error_message);
+ }
+
+ fprintf (stderr, "%s: %s\n", program_name, formatted_message);
+
+ xsyslog (LOG_PRIORITY, "%s", formatted_message);
+
+ free (formatted_message);
+ fflush (stderr);
+
+ if (status)
+ {
+ closelog ();
+ exit (status);
+ }
+}
diff --git a/current/contrib/shadow-anonftp.patch b/current/contrib/shadow-anonftp.patch
new file mode 100644
index 00000000..6938fe4f
--- /dev/null
+++ b/current/contrib/shadow-anonftp.patch
@@ -0,0 +1,147 @@
+Hello Marek,
+
+I have created a diffile against the 980403 release that adds
+functionality to newusers for automatic handling of users with only
+anonomous ftp login (using the guestgroup feature in ftpaccess, which
+means that the users home directory looks like '/home/user/./'). It also
+adds a commandline argument to specify an initial directory structure
+for such users, with a tarball normally containing the bin,lib,etc
+directories used in the chrooted environment.
+
+I am using it to automatically create chunks of users with only ftp
+access for a webserver.
+
+I have tried to follow your coding standards and I believe it is bug
+free but.. well, who knows. :) It's not much code however.
+
+I hope you find it useful. Do what you like with it, feel free to ask if
+anything is unclear.
+
+Best rgds,
+ Calle Karlsson
+ ckn@kash.se
+
+diff -uNr shadow-980403.orig/src/newusers.c shadow-980403/src/newusers.c
+--- shadow-980403.orig/src/newusers.c Fri Jan 30 00:22:43 1998
++++ shadow-980403/src/newusers.c Fri Apr 17 16:55:33 1998
+@@ -76,11 +76,35 @@
+ static void
+ usage(void)
+ {
+- fprintf(stderr, "Usage: %s [ input ]\n", Prog);
++ fprintf (stderr, "Usage: %s [-p prototype tarfile] [ input ]\n", Prog);
++ fprintf (stderr, "The prototype tarfile is only used for users\n");
++ fprintf (stderr, "marked as anonymous ftp users. It must be a full pathname.\n");
+ exit(1);
+ }
+
+ /*
++ * createuserdir - create a directory and chmod it
++ */
++
++static int
++createuserdir (char * dir, int uid, int gid, int line)
++{
++ if (mkdir (dir, 0777 & ~getdef_num("UMASK", 077))) {
++ fprintf (stderr, "%s: line %d: mkdir %s failed\n",
++ Prog, line, dir);
++ return -1;
++ }
++
++ if (chown (dir, uid, gid)) {
++ fprintf (stderr, "%s: line %d: chown %s failed\n",
++ Prog, line, dir);
++ return -1;
++ }
++
++ return 0;
++}
++
++/*
+ * add_group - create a new group or add a user to an existing group
+ */
+
+@@ -328,6 +352,8 @@
+ main(int argc, char **argv)
+ {
+ char buf[BUFSIZ];
++ char anonproto[BUFSIZ];
++ int flag;
+ char *fields[8];
+ int nfields;
+ char *cp;
+@@ -340,12 +366,23 @@
+
+ Prog = Basename(argv[0]);
+
+- if (argc > 1 && argv[1][0] == '-')
+- usage ();
++ * anonproto = '\0';
++
++ while ((flag = getopt (argc, argv, "p:h")) != EOF) {
++ switch (flag) {
++ case 'p':
++ STRFCPY(anonproto, optarg);
++ break;
++ case 'h':
++ default:
++ usage ();
++ break;
++ }
++ }
+
+- if (argc == 2) {
+- if (! freopen (argv[1], "r", stdin)) {
+- snprintf(buf, sizeof buf, "%s: %s", Prog, argv[1]);
++ if (optind < argc) {
++ if (! freopen (argv[optind], "r", stdin)) {
++ snprintf(buf, sizeof buf, "%s: %s", Prog, argv[optind]);
+ perror (buf);
+ exit (1);
+ }
+@@ -499,15 +536,36 @@
+ if (fields[6][0])
+ newpw.pw_shell = fields[6];
+
+- if (newpw.pw_dir[0] && access(newpw.pw_dir, F_OK)) {
+- if (mkdir (newpw.pw_dir,
+- 0777 & ~getdef_num("UMASK", 077)))
+- fprintf (stderr, "%s: line %d: mkdir failed\n",
+- Prog, line);
+- else if (chown (newpw.pw_dir,
+- newpw.pw_uid, newpw.pw_gid))
+- fprintf (stderr, "%s: line %d: chown failed\n",
+- Prog, line);
++ if (newpw.pw_dir[0]) {
++ char * userdir = strdup (newpw.pw_dir);
++ char * anonpart;
++ int rc;
++
++ if ((anonpart = strstr (userdir, "/./"))) {
++ * anonpart = '\0';
++ anonpart += 2;
++ }
++
++ if (access(userdir, F_OK))
++ rc = createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line);
++ else
++ rc = 0;
++
++ if (rc == 0 && anonpart) {
++ if (* anonproto) {
++ char cmdbuf [BUFSIZ];
++ snprintf(cmdbuf, sizeof cmdbuf,
++ "cd %s; tar xf %s",
++ userdir, anonproto);
++ system (cmdbuf);
++ }
++ if (strlen (anonpart) > 1) {
++ strcat (userdir, anonpart);
++ if (access (userdir, F_OK))
++ createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line);
++ }
++ }
++ free (userdir);
+ }
+
+ /*
diff --git a/current/contrib/udbachk.v012.tgz b/current/contrib/udbachk.v012.tgz
new file mode 100644
index 00000000..82bd3204
--- /dev/null
+++ b/current/contrib/udbachk.v012.tgz
Binary files differ
diff --git a/current/debian/FILES b/current/debian/FILES
new file mode 100644
index 00000000..eb7d2375
--- /dev/null
+++ b/current/debian/FILES
@@ -0,0 +1,70 @@
+ groups
+ groups.1
+ id
+ id.1
+ pw_auth.3
+ scologin
+ shadow.3
+ sulogin
+ sulogin.8
+login faillog
+login faillog.5
+login faillog.8
+login lastlog
+login lastlog.8
+login login
+login login.1
+login login.access.5
+login login.defs.5
+login logoutd
+login logoutd.8
+login newgrp
+login newgrp.1
+login porttime.5
+passwd chage
+passwd chage.1
+passwd chfn
+passwd chfn.1
+passwd chpasswd
+passwd chpasswd.8
+passwd chsh
+passwd chsh.1
+passwd dpasswd
+passwd dpasswd.8
+passwd expiry
+passwd gpasswd
+passwd gpasswd.1
+passwd groupadd
+passwd groupadd.8
+passwd groupdel
+passwd groupdel.8
+passwd groupmod
+passwd groupmod.8
+passwd grpck
+passwd grpck.8
+passwd grpconv
+passwd grpunconv
+passwd mkpasswd
+passwd mkpasswd.8
+passwd newusers
+passwd newusers.8
+passwd passwd
+passwd passwd.1
+passwd passwd.5
+passwd pwauth.8
+passwd pwck
+passwd pwck.8
+passwd pwconv
+passwd pwconv.8
+passwd pwunconv
+passwd pwunconv.8
+passwd shadow.5
+passwd useradd
+passwd useradd.8
+passwd userdel
+passwd userdel.8
+passwd usermod
+passwd usermod.8
+secure-su su
+secure-su su.1
+secure-su suauth.5
diff --git a/current/debian/Makefile.am b/current/debian/Makefile.am
new file mode 100644
index 00000000..b79efc65
--- /dev/null
+++ b/current/debian/Makefile.am
@@ -0,0 +1,9 @@
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+EXTRA_DIST = FILES changelog checksums control control.gnu control.linux \
+ login.conffiles login.copyright login.postinst login.postrm login.preinst \
+ login.prerm logoutd.init passwd.conffiles passwd.copyright \
+ passwd.cron passwd.init passwd.postinst passwd.postrm porttime rules \
+ secure-su.README secure-su.conffiles secure-su.copyright secure-su.postrm \
+ secure-su.preinst securetty tar.c
diff --git a/current/debian/Makefile.in b/current/debian/Makefile.in
new file mode 100644
index 00000000..4e64b180
--- /dev/null
+++ b/current/debian/Makefile.in
@@ -0,0 +1,212 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+EXTRA_DIST = FILES changelog checksums control control.gnu control.linux login.conffiles login.copyright login.postinst login.postrm login.preinst login.prerm logoutd.init passwd.conffiles passwd.copyright passwd.cron passwd.init passwd.postinst passwd.postrm porttime rules secure-su.README secure-su.conffiles secure-su.copyright secure-su.postrm secure-su.preinst securetty tar.c
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps debian/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = debian
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/debian/changelog b/current/debian/changelog
new file mode 100644
index 00000000..b1548b5e
--- /dev/null
+++ b/current/debian/changelog
@@ -0,0 +1,175 @@
+shadow (19990827) unstable; urgency=low
+
+ * upstream upgrade, see CHANGES for more details. Note: this is
+ not the official Debian changelog entry - it is here only for
+ dpkg-buildpackage to work (so I can build and test this package
+ on my system). To the Debian maintainers: please feel free to
+ replace this entry with your own, and put your name (instead of
+ mine) in the debian/control Maintainer field. Thanks, and keep
+ up the good work!
+
+ -- Marek Michalkiewicz <marekm@linux.org.pl> Fri, 27 Aug 1999 21:00:00 +0200
+
+shadow (980403-0.3.2) unstable; urgency=low
+
+ * configure.in patched for utmpx.h (for arm)
+
+ -- Jim Pick <jim@jimpick.com> Sun, 4 Oct 1998 19:06:15 -0700
+
+shadow (980403-0.3.1) frozen unstable; urgency=low
+
+ * Non maintainer upload.
+ changes.{guess,sub} changed to recognize a Arm architecture.
+
+ -- Turbo Fredriksson <turbo@debian.org> Fri, 14 Aug 1998 22:37:58 -0400
+
+shadow (980403-0.3) frozen unstable; urgency=high
+
+ * Non maintainer upload.
+ * src/login.c: Applied patch from <marekm@i17linuxb.ists.pwr.wroc.pl> to
+ fix security hole of login not checking the return code from setgid(),
+ initgroups() or setuid(). [#24710]
+
+ -- James Troup <james@nocrew.org> Fri, 17 Jul 1998 18:56:31 +0100
+
+shadow (980403-0.2) frozen unstable; urgency=low
+
+ * (login.defs): fixed UMASK
+ (thanks to James Troup for noticing my screwup :)
+ * Pruned non-Debian changelog entries.
+
+ -- Joel Klecker <jk@espy.org> Mon, 11 May 1998 11:25:22 -0700
+
+shadow (980403-0.1) frozen unstable; urgency=low
+
+ * Non-maintainer release.
+ * New upstream release (18225).
+ * (debian/login.postinst)
+ * Use 'touch' instead of 'cat >' when creating /var/log/faillog
+ (15998,16187,21687).
+ * No longer fails if no previous configured version exists (11433).
+ * (gpasswd): now checks which user invoked it before calling setuid() (18132).
+ * (debian/passwd.postinst): removed bashism (13753).
+ * (groupmod): NULL dereference fixed upstream, as a result, it no longer
+ dumps core when changing group name (16893,17894).
+ * (useradd): no longer segfaults if /etc/default/useradd is missing (18628).
+ * (login.defs.1): now documents more options (13485).
+ * (source): includes 'missing' (13815,18133,21280).
+ * (login.1):
+ * Removed mention of "d_passwd(5)", which doesn't exist,
+ and login.defs.5 now documents /etc/dialups (15176).
+ * Added /etc/nologin to FILES section and reference nologin(5) (21695).
+ * The URL mentioned in Bug#15391 is no longer valid.
+ * (login.defs): no longer sets ULIMIT (17529).
+ * (login):
+ * No longer uses static buffers for group lines (17532).
+ * Doesn't seem to make assumptions about gid_t any longer (21767).
+ * (faillog.8): s-/usr/adm-/var/log-g (19974).
+ * (lastlog.8): notes that "some systems" use /var/log instead of
+ /usr/adm (21746).
+ * Install upstream changelog as 'changelog.gz' as per policy (20052).
+ * (secure-su): Changed /etc/suauth to reference the group 'root'
+ instead of 'wheel' (17593).
+
+ -- Joel Klecker <jk@espy.org> Thu, 30 Apr 1998 18:32:12 -0700
+
+shadow (970616-1) unstable; urgency=low
+
+ * Upstream upgrade.
+ * chage works (10561).
+ * Fix NIS behavior (5634,8734,10032,10545,10984,11160,12064).
+ * Wrote pwconv,pwunconv,grpconv,grpunconv manpage (10940).
+ * vipw fixes (10521,10696,11618,11924,12184,13001)
+ * Fixes for new automake.
+ * Compile with glibc2. (8627,8777,9824,11713,11719,12082,12108,11442).
+ * debian/rules fixes (8876,12468).
+ * /etc/login.defs: UMASK=002 (9102).
+ * chown /dev/vcs* on login (9421,13255).
+ * Added tty9-tty12 to /etc/securetty (11644).
+ * Provide template and manpage for /etc/limits (12289).
+ * Fix security hole in postinst (11769).
+ * login fills out ut_addr field in utmp (10701).
+ * shadowconfig.sh fixes (9189,9328,9386,10968,12452,12469).
+ * Overcome postinst bug in old shadow-passwd package (9939,12120).
+ * useradd default GROUP=100 (9244).
+ * Allow 8 bit chars in chfn (12367).
+ * secure-su - set HOME, use SHELL if set (11003,11189).
+
+ -- Guy Maor <maor@ece.utexas.edu> Fri, 26 Sep 1997 19:23:42 -0500
+
+shadow (970616) unstable; urgency=low
+
+ * vipw preserves permissions on edited files (10521).
+ * various other bug fixes.
+
+ -- Marek Michalkiewicz <marekm@piast.t19.ds.pwr.wroc.pl> Mon, 16 Jun 1997 02:02:00 +0200
+
+shadow (970601) unstable; urgency=low
+
+ * Fix typo in libmisc/mail.c causing login to segfault.
+
+ -- Marek Michalkiewicz <marekm@piast.t19.ds.pwr.wroc.pl> Mon, 2 Jun 1997 07:33:00 +0200
+
+shadow (970502-2) unstable; urgency=low
+
+ * Fixes to shadow group support (grpconv didn't work).
+
+ -- Marek Michalkiewicz <marekm@piast.t19.ds.pwr.wroc.pl> Fri, 2 May 1997 15:48:00 +0200
+
+shadow (970502-1) unstable; urgency=low
+
+ * Upstream upgrade.
+
+ -- Marek Michalkiewicz <marekm@piast.t19.ds.pwr.wroc.pl> Fri, 2 May 1997 03:18:00 +0200
+
+shadow (961025-2) frozen unstable; urgency=medium
+
+ * Fix useradd -D segfault (8098, 8152, 8733).
+ * Fix shadowconfig - permfix only on xlock; /etc/init.d/xdm rewrite, chmod
+ (8102, 8320, 8333, 8708).
+ * Remove HOWTO from usr/doc/passwd as it's in linux-doc (8150).
+ * Fixes to su.1 (8153).
+ * login, passwd, su each conflict and replace with the old shadow-*
+ version. (8269, 8290, 8393, 8394).
+ * Put /etc/shells back in passwd (8328).
+ * Fixed login.postinst for upgrade from shadow-login (8392).
+ * Added -e to pwck for use in shadowconfig: reports only errors, no
+ warnings (8542).
+ * Wrote shadowconfig.8 (8588).
+
+ -- Guy Maor <maor@ece.utexas.edu> Sat, 19 Apr 1997 02:34:59 -0500
+
+shadow (961025-1) unstable; urgency=low
+
+ * Upstream upgrade, new source format.
+
+ -- Guy Maor <maor@ece.utexas.edu> Mon, 10 Feb 1997 02:56:56 -0600
+
+shadow (960530-1) experimental; urgency=LOW
+
+ * Added grpunconv script
+ * Changed prerm/postinst scripts to remove/create shadowed group
+ file
+ * Added vipw/vigr binaries
+ * Renamed package to shadow-passwd
+ * Added packages shadow-su and shadow-login
+ * Added 'Essential: yes' to be able to replace passwd and login
+ * Section now base for shadow-passwd and shadow-login
+ * Added /etc/shell conffile
+ * Added /etc/securetty conffile
+ * Added new conffile /etc/suauth. Set it up so only users in group 0
+ can su to root.
+
+shadow (960810-1) base; urgency=LOW
+
+ * Added useradd default file so that default group is no longer 1
+ * Also corrected the useradd manpage
+ * Replaced grpunconv script by real binary which does correct
+ locking.
+ * Added 'source' field control file to control files
+ * Changed version naming in debian.rules
+ * New upstream version
+
+Local variables:
+mode: debian-changelog
+End:
diff --git a/current/debian/checksums b/current/debian/checksums
new file mode 100755
index 00000000..9d227c30
--- /dev/null
+++ b/current/debian/checksums
@@ -0,0 +1,7 @@
+#!/bin/sh
+# This script is run from debian/rules to generate MD5 checksums
+# for all files in the package.
+# $Id: checksums,v 1.1 1997/12/14 21:05:37 marekm Exp $
+set -e
+cd $1
+md5sum `find * -type f ! -regex "DEBIAN/.*"` >DEBIAN/md5sums </dev/null
diff --git a/current/debian/control b/current/debian/control
new file mode 100644
index 00000000..430c4b3a
--- /dev/null
+++ b/current/debian/control
@@ -0,0 +1,41 @@
+Source: shadow
+Section: base
+Priority: required
+Maintainer: Marek Michalkiewicz <marekm@linux.org.pl>
+Standards-Version: 2.3.0.0
+
+Package: login
+Architecture: any
+Pre-Depends: ${shlibs:Depends}
+Conflicts: shadow-login
+Replaces: shadow-login, shadow-passwd
+Essential: yes
+Section: base
+Priority: required
+Description: Sign on to the system.
+ login and newgrp change the user and group.
+
+Package: passwd
+Architecture: any
+Depends: ${shlibs:Depends}, login (>= 970502-1)
+Conflicts: shadow-passwd
+Replaces: shadow-passwd
+Replaces: manpages (<=1.15-2)
+Section: base
+Priority: required
+Description: Change and administer password and group data.
+ This package includes passwd, chsh, chfn, and many other programs to
+ maintain password and group data.
+ .
+ Shadow passwords are supported. See /usr/doc/passwd/README.Debian
+
+Package: secure-su
+Architecture: any
+Depends: ${shlibs:Depends}, login (>= 970502-1)
+Conflicts: shadow-su
+Replaces: shadow-su
+Section: admin
+Priority: optional
+Description: su with more security options
+ secure-su offers more security options than the normal su, such as a
+ wheel group, and from-user and to-user specific restrictions.
diff --git a/current/debian/control.gnu b/current/debian/control.gnu
new file mode 100644
index 00000000..5b052739
--- /dev/null
+++ b/current/debian/control.gnu
@@ -0,0 +1,16 @@
+Source: shadow
+Section: base
+Priority: required
+Maintainer: Guy Maor <maor@debian.org>
+Standards-Version: 2.3.0.0
+
+Package: passwd
+Architecture: any
+Depends: ${shlibs:Depends}
+Section: base
+Priority: required
+Description: Change and administer password and group data.
+ This package includes passwd, chsh, chfn, and many other programs to
+ maintain password and group data.
+ .
+ Shadow passwords are supported. See /usr/doc/passwd/README.Debian
diff --git a/current/debian/control.linux b/current/debian/control.linux
new file mode 100644
index 00000000..430c4b3a
--- /dev/null
+++ b/current/debian/control.linux
@@ -0,0 +1,41 @@
+Source: shadow
+Section: base
+Priority: required
+Maintainer: Marek Michalkiewicz <marekm@linux.org.pl>
+Standards-Version: 2.3.0.0
+
+Package: login
+Architecture: any
+Pre-Depends: ${shlibs:Depends}
+Conflicts: shadow-login
+Replaces: shadow-login, shadow-passwd
+Essential: yes
+Section: base
+Priority: required
+Description: Sign on to the system.
+ login and newgrp change the user and group.
+
+Package: passwd
+Architecture: any
+Depends: ${shlibs:Depends}, login (>= 970502-1)
+Conflicts: shadow-passwd
+Replaces: shadow-passwd
+Replaces: manpages (<=1.15-2)
+Section: base
+Priority: required
+Description: Change and administer password and group data.
+ This package includes passwd, chsh, chfn, and many other programs to
+ maintain password and group data.
+ .
+ Shadow passwords are supported. See /usr/doc/passwd/README.Debian
+
+Package: secure-su
+Architecture: any
+Depends: ${shlibs:Depends}, login (>= 970502-1)
+Conflicts: shadow-su
+Replaces: shadow-su
+Section: admin
+Priority: optional
+Description: su with more security options
+ secure-su offers more security options than the normal su, such as a
+ wheel group, and from-user and to-user specific restrictions.
diff --git a/current/debian/login.conffiles b/current/debian/login.conffiles
new file mode 100644
index 00000000..c1d83cba
--- /dev/null
+++ b/current/debian/login.conffiles
@@ -0,0 +1,6 @@
+/etc/login.defs
+/etc/login.access
+/etc/securetty
+/etc/porttime
+/etc/limits
+/etc/init.d/logoutd
diff --git a/current/debian/login.copyright b/current/debian/login.copyright
new file mode 100644
index 00000000..a848548c
--- /dev/null
+++ b/current/debian/login.copyright
@@ -0,0 +1,76 @@
+This is Debian/GNU Linux's prepackaged version of login and related
+utilities.
+
+It was downloaded from: <ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/>.
+
+This software is copyright 1988 - 1994, Julianne Frances Haugh.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+This source code is currently archived on ftp.uu.net in the
+comp.sources.misc portion of the USENET archives. You may also contact
+the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have
+any questions regarding this package.
+
+THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL
+LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE
+FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO
+OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS
+ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL
+LOSS OF INFORMATION OR MACHINE RESOURCES.
+
+Special thanks are due to Chip Rosenthal for his fine testing efforts;
+to Steve Simmons for his work in porting this code to BSD; and to Bill
+Kennedy for his contributions of LaserJet printer time and energies.
+Also, thanks for Dennis L. Mumaugh for the initial shadow password
+information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System
+V Release 4 changes. Effort in porting to SunOS has been contributed
+by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr.
+(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release
+4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au).
+Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl)
+for taking over the Linux port of this software.
+
+Source files: login_access.c, login_desrpc.c, login_krb.c are derived
+from the logdaemon-5.0 package, which is under the following license:
+
+/************************************************************************
+* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+* may be covered by other copyrights (as noted in the file itself.)
+*
+* This material was originally written and compiled by Wietse Venema at
+* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+* 1992, 1993, 1994 and 1995.
+*
+* Redistribution and use in source and binary forms are permitted
+* provided that this entire copyright notice is duplicated in all such
+* copies.
+*
+* This software is provided "as is" and without any expressed or implied
+* warranties, including, without limitation, the implied warranties of
+* merchantibility and fitness for any particular purpose.
+************************************************************************/
+
diff --git a/current/debian/login.postinst b/current/debian/login.postinst
new file mode 100644
index 00000000..32b19a06
--- /dev/null
+++ b/current/debian/login.postinst
@@ -0,0 +1,42 @@
+#!/bin/sh
+set -e
+
+[ "$1" = configure -a "$2" ] \
+ && dpkg --compare-versions $2 lt 961025 \
+ || [ -z "$2" ] \
+ || exit 0
+
+if [ -f /etc/usertty ] ; then
+ cat > /etc/usertty$$ <<EOF
+# WARNING: This file isn't used by the current version of login.
+# Similiar functionality is available in /etc/login.defs,
+# /etc/login.access, and /etc/porttime. See login.defs(5),
+# login.access(5), and porttime(5) for details. You may safely remove
+# this file after configuring the other three.
+#
+EOF
+ cat /etc/usertty >> /etc/usertty$$
+ mv -f /etc/usertty$$ /etc/usertty
+
+ if egrep -vqn '^#|^ *$' /etc/usertty ; then cat <<EOF
+You've configured /etc/usertty, but the current version of login no
+longer supports it. Similiar functionality is available in other
+files, which you will have to configure for your purposes.
+
+A more detailed explanation has been prepended to /etc/usertty.
+You'll have to do some configuration later.
+
+Please hit return to confirm.
+EOF
+
+ read
+ fi
+fi
+
+if [ ! -f /var/log/faillog ] ; then
+ touch /var/log/faillog
+ chown root:root /var/log/faillog
+ chmod 644 /var/log/faillog
+fi
+
+update-rc.d logoutd defaults > /dev/null
diff --git a/current/debian/login.postrm b/current/debian/login.postrm
new file mode 100644
index 00000000..ccfa914f
--- /dev/null
+++ b/current/debian/login.postrm
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+if [ "$1" = "purge" ] ; then
+ update-rc.d logoutd remove >/dev/null
+fi
diff --git a/current/debian/login.preinst b/current/debian/login.preinst
new file mode 100644
index 00000000..96637b51
--- /dev/null
+++ b/current/debian/login.preinst
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -e
+dpkg --assert-support-predepends ||
+( echo -e "\nPlease upgrade to a newer version of dpkg\n"; exit 1; )
diff --git a/current/debian/login.prerm b/current/debian/login.prerm
new file mode 100644
index 00000000..ba1301b3
--- /dev/null
+++ b/current/debian/login.prerm
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -e
+
+case $1 in
+ remove|upgrade|deconfigure)
+ /etc/init.d/logoutd stop
+ ;;
+esac
diff --git a/current/debian/logoutd.init b/current/debian/logoutd.init
new file mode 100644
index 00000000..60594465
--- /dev/null
+++ b/current/debian/logoutd.init
@@ -0,0 +1,36 @@
+#! /bin/sh
+# start/stop logoutd
+
+set -e
+
+DAEMON=/usr/sbin/logoutd
+test -f $DAEMON || exit 0
+
+# Most people won't need logoutd(8) running, so we'll only run it if
+# /etc/porttime has non-comment lines.
+egrep -vq '^#|^ *$' /etc/porttime || exit 0
+
+case "$1" in
+ start)
+ echo -n "Starting login time and port restriction enforcer: logoutd"
+ start-stop-daemon --start --quiet --exec $DAEMON
+ echo "."
+ ;;
+ stop)
+ echo -n "Stopping login time and port restriction enforcer: logoutd"
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ echo "."
+ ;;
+ force-reload|restart)
+ $0 stop
+ $0 start
+ ;;
+ reload)
+ ;;
+ *)
+ echo "Usage: /etc/init.d/logoutd start|stop|restart"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/current/debian/passwd.conffiles b/current/debian/passwd.conffiles
new file mode 100644
index 00000000..48979eaf
--- /dev/null
+++ b/current/debian/passwd.conffiles
@@ -0,0 +1,3 @@
+/etc/cron.daily/passwd
+/etc/init.d/passwd
+/etc/shells
diff --git a/current/debian/passwd.copyright b/current/debian/passwd.copyright
new file mode 100644
index 00000000..701d899f
--- /dev/null
+++ b/current/debian/passwd.copyright
@@ -0,0 +1,55 @@
+This is Debian/GNU Linux's prepackaged version of the passwd
+utilities.
+
+It was downloaded from: <ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/>.
+
+This software is copyright 1988 - 1994, Julianne Frances Haugh.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+This source code is currently archived on ftp.uu.net in the
+comp.sources.misc portion of the USENET archives. You may also contact
+the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have
+any questions regarding this package.
+
+THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL
+LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE
+FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO
+OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS
+ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL
+LOSS OF INFORMATION OR MACHINE RESOURCES.
+
+Special thanks are due to Chip Rosenthal for his fine testing efforts;
+to Steve Simmons for his work in porting this code to BSD; and to Bill
+Kennedy for his contributions of LaserJet printer time and energies.
+Also, thanks for Dennis L. Mumaugh for the initial shadow password
+information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System
+V Release 4 changes. Effort in porting to SunOS has been contributed
+by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr.
+(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release
+4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au).
+Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl)
+for taking over the Linux port of this software.
diff --git a/current/debian/passwd.cron b/current/debian/passwd.cron
new file mode 100644
index 00000000..4bc868ef
--- /dev/null
+++ b/current/debian/passwd.cron
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# cron.daily script to check integrity of the password and group files
+
+test -f /usr/sbin/pwck || exit 0
+
+pwck -q -r
+grpck -r
diff --git a/current/debian/passwd.init b/current/debian/passwd.init
new file mode 100755
index 00000000..83ef2071
--- /dev/null
+++ b/current/debian/passwd.init
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# /etc/init.d/passwd
+# script to check integrity of the password and group files at system startup
+#
+
+set -e
+test -f /usr/sbin/pwck || exit 0
+
+case "$1" in
+ start)
+ echo -n 'Checking password and group files... '
+ pwck -q -r
+ grpck -r
+ echo "done."
+ ;;
+ stop|restart|reload|force-reload)
+ ;;
+ *)
+ echo "Usage: /etc/init.d/passwd start"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/current/debian/passwd.postinst b/current/debian/passwd.postinst
new file mode 100644
index 00000000..bb8ed870
--- /dev/null
+++ b/current/debian/passwd.postinst
@@ -0,0 +1,41 @@
+#!/bin/sh
+set -e
+
+if [ configure != "$1" ] ; then
+ exit 0
+fi
+
+# passwd 961025-1 incorrectly did permfix on sulogin and xdm-shadow in
+# shadowconfig
+permfix () {
+ [ -f $1 ] || return 0
+ chown root:root $1
+ chmod 755 $1
+}
+permfix /sbin/sulogin
+permfix /usr/X11R6/bin/xdm-shadow
+
+# check password and group files at boot time
+update-rc.d passwd start 60 S . >/dev/null
+
+grep -q '^shadow:[^:]*:42' /etc/group && exit 0
+groupadd -g 42 shadow || (
+ cat <<EOF
+Group ID 42 has been relegated for the shadow group. You have either
+used 42 yourself or created a shadow group with a different ID.
+Please correct this problem and reconfigure with ``dpkg --configure passwd''.
+
+Note that both user and group IDs in the range 0-99 are globally
+allocated by the Debian project and must be the same on every Debian
+system.
+EOF
+
+ exit 1
+)
+
+# overcome bug in old shadow-passwd postinst; these are harmless on other
+# systems
+chmod 644 /etc/passwd /etc/group
+chown root:root /etc/passwd /etc/group
+
+exit 0
diff --git a/current/debian/passwd.postrm b/current/debian/passwd.postrm
new file mode 100644
index 00000000..57f19c19
--- /dev/null
+++ b/current/debian/passwd.postrm
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+if [ "$1" = "purge" ] ; then
+ update-rc.d passwd remove >/dev/null
+fi
diff --git a/current/debian/porttime b/current/debian/porttime
new file mode 100644
index 00000000..5888d63a
--- /dev/null
+++ b/current/debian/porttime
@@ -0,0 +1,8 @@
+# /etc/porttime contains user time restrictions.
+# See porttime(5).
+
+# If you add restrictions to this file, be sure that
+# PORTTIME_CHECKS_ENAB is set to `yes' in /etc/login.defs. logoutd(8)
+# will be started automatically on bootup if this file contains
+# non-comment lines. You may also start it manually with
+# `/etc/init.d/logoutd start'.
diff --git a/current/debian/rules b/current/debian/rules
new file mode 100755
index 00000000..63284d78
--- /dev/null
+++ b/current/debian/rules
@@ -0,0 +1,159 @@
+#!/usr/bin/make -f
+
+# FIXME - this is out of date, please update for current Debian
+
+package = shadow
+
+# see dpkg-architecture(8)
+DEB_BUILD_ARCH := $(shell dpkg --print-installation-architecture)
+DEB_BUILD_GNU_CPU := $(patsubst hurd-%,%,$(DEB_BUILD_ARCH))
+ifeq ($(filter-out hurd-%,$(DEB_BUILD_ARCH)),)
+ DEB_BUILD_GNU_SYSTEM := gnu
+else
+ DEB_BUILD_GNU_SYSTEM := linux
+endif
+DEB_BUILD_GNU_TYPE=$(DEB_BUILD_GNU_CPU)-$(DEB_BUILD_GNU_SYSTEM)
+
+DEB_HOST_GNU_SYSTEM=$(DEB_BUILD_GNU_SYSTEM)
+DEB_HOST_GNU_TYPE=$(DEB_BUILD_GNU_TYPE)
+
+ifeq ($(DEB_HOST_GNU_SYSTEM),linux)
+package-list = binary-login binary-passwd binary-su
+else
+package-list = binary-passwd
+endif
+
+# for "exec login" to work for ordinary users, /bin/login needs to be setuid
+# but very few people use this feature, so we make it non-setuid by default
+LOGIN_PERM = 0755
+
+build:
+ $(checkdir)
+ cp -a debian/control.$(DEB_HOST_GNU_SYSTEM) debian/control
+ # shared lib support is untested, so...
+ ./configure --disable-shared --disable-desrpc \
+ --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+ $(MAKE)
+ touch build
+
+clean:
+ $(checkdir)
+ rm -f build debian/tar
+ -$(MAKE) -i distclean
+ rm -rf {libmisc,lib,src}/.deps
+ rm -rf debian/tmp{-l,-p,-s} debian/{files*,substvars}
+ cp -a debian/control.linux debian/control
+ find . -name '*~' -print0 | xargs -0 rm -f
+
+binary-indep: checkroot build
+ $(checkdir)
+
+binary-arch: $(package-list)
+
+binary-login: checkroot build
+ $(checkdir)
+ -rm -rf debian/tmp-l
+ install -d debian/tmp-l/{DEBIAN,bin,etc/init.d,usr/{bin,man/man{1,5,8},doc/login,sbin}}
+ install -s -m$(LOGIN_PERM) src/login debian/tmp-l/bin/
+ install -s -m4755 src/newgrp debian/tmp-l/usr/bin/
+ install -s src/{faillog,lastlog} debian/tmp-l/usr/bin/
+ install -s src/logoutd debian/tmp-l/usr/sbin/
+ install -m644 man/{login.1,newgrp.1} debian/tmp-l/usr/man/man1/
+ install -m644 man/{login.defs.5,login.access.5,porttime.5,faillog.5,limits.5} debian/tmp-l/usr/man/man5/
+ install -m644 man/{faillog.8,logoutd.8,lastlog.8} debian/tmp-l/usr/man/man8/
+ ln -s newgrp debian/tmp-l/usr/bin/sg
+ ln -s newgrp.1.gz debian/tmp-l/usr/man/man1/sg.1.gz
+ install -m600 etc/login.defs.linux debian/tmp-l/etc/login.defs
+ install -m600 etc/{login.access,limits} debian/{securetty,porttime} debian/tmp-l/etc/
+ install debian/logoutd.init debian/tmp-l/etc/init.d/logoutd
+ install -m644 debian/changelog debian/tmp-l/usr/doc/login/changelog.Debian
+ install -m644 doc/CHANGES debian/tmp-l/usr/doc/login/changelog
+ find debian/tmp-l/usr/{doc,man} -type f | xargs gzip -9
+ install -m644 debian/login.copyright debian/tmp-l/usr/doc/login/copyright
+ install debian/login.preinst debian/tmp-l/DEBIAN/preinst
+ install debian/login.postinst debian/tmp-l/DEBIAN/postinst
+ install debian/login.prerm debian/tmp-l/DEBIAN/prerm
+ install debian/login.postrm debian/tmp-l/DEBIAN/postrm
+ install -m644 debian/login.conffiles debian/tmp-l/DEBIAN/conffiles
+ dpkg-shlibdeps debian/tmp-l/{bin/*,usr/bin/*,usr/sbin/*}
+ dpkg-gencontrol -isp -plogin -Pdebian/tmp-l
+ ./debian/checksums debian/tmp-l
+
+binary-passwd: checkroot build
+ $(checkdir)
+ -rm -rf debian/tmp-p
+ install -d debian/tmp-p/{DEBIAN,etc/{cron.daily,init.d},usr/{sbin,bin,man/{man1,man5,man8},doc/passwd}}
+ install -m644 etc/shells debian/tmp-p/etc/
+ install debian/passwd.cron debian/tmp-p/etc/cron.daily/passwd
+ install debian/passwd.init debian/tmp-p/etc/init.d/passwd
+ install -s -m4755 src/{chage,chfn,chsh,expiry,gpasswd,passwd} debian/tmp-p/usr/bin/
+ install -s src/{chpasswd,groupadd,groupdel,groupmod,grpck,grpconv,grpunconv} \
+ src/{newusers,pwck,pwconv,pwunconv,useradd,userdel} \
+ src/{dpasswd,usermod,vipw} debian/tmp-p/usr/sbin/
+ install -m644 man/{chage.1,chfn.1,chsh.1,gpasswd.1,passwd.1} \
+ debian/tmp-p/usr/man/man1/
+ install -m644 man/{chpasswd.8,groupadd.8,groupdel.8,groupmod.8,grpck.8} \
+ man/{newusers.8,pwck.8,dpasswd.8} \
+ man/{useradd.8,userdel.8,usermod.8,vipw.8,shadowconfig.8,pwconv.8} \
+ debian/tmp-p/usr/man/man8/
+ install -m644 man/{passwd.5,shadow.5} debian/tmp-p/usr/man/man5/
+ ln -s vipw debian/tmp-p/usr/sbin/vigr
+ ln -s vipw.8.gz debian/tmp-p/usr/man/man8/vigr.8.gz
+ for i in pwunconv.8.gz grpconv.8.gz grpunconv.8.gz ; do \
+ ln -s pwconv.8.gz debian/tmp-p/usr/man/man8/$$i ; done
+ install -m644 debian/changelog debian/tmp-p/usr/doc/passwd/changelog.Debian
+ install -m644 doc/{CHANGES,README,README.limits,README.linux,README.debian} \
+ debian/tmp-p/usr/doc/passwd/
+ find debian/tmp-p/usr/{doc,man} -type f | xargs gzip -9f
+ install -m644 debian/passwd.copyright debian/tmp-p/usr/doc/passwd/copyright
+ install debian/login.preinst debian/tmp-p/DEBIAN/preinst
+ install debian/passwd.postinst debian/tmp-p/DEBIAN/postinst
+ install debian/passwd.postrm debian/tmp-p/DEBIAN/postrm
+ install -m644 debian/passwd.conffiles debian/tmp-p/DEBIAN/conffiles
+ dpkg-shlibdeps debian/tmp-p/usr/{bin/*,sbin/*}
+ # dpkg-shlibdeps fails on scripts, so install them now...
+ install src/shadowconfig.sh debian/tmp-p/usr/sbin/shadowconfig
+ifeq ($(DEB_HOST_GNU_SYSTEM),gnu)
+ install etc/login.defs.hurd debian/tmp-p/etc/login.defs
+ echo "/etc/login.defs" >> debian/tmp-p/DEBIAN/conffiles
+endif
+ dpkg-gencontrol -isp -ppasswd -Pdebian/tmp-p
+ ./debian/checksums debian/tmp-p
+
+binary-su: checkroot build
+ $(checkdir)
+ -rm -rf debian/tmp-s
+ install -d debian/tmp-s/{DEBIAN,etc,bin,usr/{doc/secure-su,man/man{1,5}}}
+ install -s -m4755 src/su debian/tmp-s/bin/
+ install -m644 etc/suauth debian/tmp-s/etc/
+ install -m644 man/suauth.5 debian/tmp-s/usr/man/man5/
+ install -m644 man/su.1 debian/tmp-s/usr/man/man1/
+ install -m644 debian/secure-su.README debian/tmp-s/usr/doc/secure-su/README
+ install -m644 debian/changelog debian/tmp-s/usr/doc/secure-su/
+ find debian/tmp-s/usr/{doc,man} -type f | xargs gzip -9f
+ install -m644 debian/secure-su.copyright debian/tmp-s/usr/doc/secure-su/copyright
+ install debian/secure-su.preinst debian/tmp-s/DEBIAN/preinst
+ install debian/secure-su.postrm debian/tmp-s/DEBIAN/postrm
+ install -m644 debian/secure-su.conffiles debian/tmp-s/DEBIAN/conffiles
+ dpkg-shlibdeps debian/tmp-s/bin/su
+ dpkg-gencontrol -isp -psecure-su -Pdebian/tmp-s
+ ./debian/checksums debian/tmp-s
+
+define checkdir
+ test -f lib/shadow.c -a -f debian/rules
+endef
+
+
+binary: binary-indep binary-arch
+
+source diff:
+ @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
+
+checkroot:
+ $(checkdir)
+# test root = "`whoami`"
+
+.PHONY: binary binary-arch binary-indep clean checkroot
+
+# Local Variables:
+# mode:Makefile
diff --git a/current/debian/secure-su.README b/current/debian/secure-su.README
new file mode 100644
index 00000000..723f37a0
--- /dev/null
+++ b/current/debian/secure-su.README
@@ -0,0 +1,4 @@
+The su from shellutils is diverted into /bin/secure-su. That
+directory MUST be owned by root and have permissions 700. Otherwise
+you will lost any security advantages you will gain by installing
+secure-su as users can still invoke the old su.
diff --git a/current/debian/secure-su.conffiles b/current/debian/secure-su.conffiles
new file mode 100644
index 00000000..2853262a
--- /dev/null
+++ b/current/debian/secure-su.conffiles
@@ -0,0 +1 @@
+/etc/suauth
diff --git a/current/debian/secure-su.copyright b/current/debian/secure-su.copyright
new file mode 100644
index 00000000..de1479c6
--- /dev/null
+++ b/current/debian/secure-su.copyright
@@ -0,0 +1,54 @@
+This is Debian/GNU Linux's prepackaged version of secure-su.
+
+It was downloaded from: <ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/>.
+
+This software is copyright 1988 - 1994, Julianne Frances Haugh.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+This source code is currently archived on ftp.uu.net in the
+comp.sources.misc portion of the USENET archives. You may also contact
+the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have
+any questions regarding this package.
+
+THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL
+LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE
+FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO
+OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS
+ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL
+LOSS OF INFORMATION OR MACHINE RESOURCES.
+
+Special thanks are due to Chip Rosenthal for his fine testing efforts;
+to Steve Simmons for his work in porting this code to BSD; and to Bill
+Kennedy for his contributions of LaserJet printer time and energies.
+Also, thanks for Dennis L. Mumaugh for the initial shadow password
+information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System
+V Release 4 changes. Effort in porting to SunOS has been contributed
+by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr.
+(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release
+4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au).
+Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl)
+for taking over the Linux port of this software.
diff --git a/current/debian/secure-su.postrm b/current/debian/secure-su.postrm
new file mode 100644
index 00000000..aef1e6ab
--- /dev/null
+++ b/current/debian/secure-su.postrm
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+if [ remove = "$1" ] ; then
+ dpkg-divert --package secure-su --remove --rename \
+ --divert /bin/secure-su/su /bin/su
+ dpkg-divert --package secure-su --remove --rename \
+ --divert /usr/man/man1/gnu-su.1.gz /usr/man/man1/su.1.gz
+ rm /bin/secure-su/README.gz
+ rmdir /bin/secure-su || true
+fi
diff --git a/current/debian/secure-su.preinst b/current/debian/secure-su.preinst
new file mode 100644
index 00000000..d5522c2e
--- /dev/null
+++ b/current/debian/secure-su.preinst
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -e
+
+if [ install = "$1" ] ; then
+ # dpkg-divert uses rename so can't do cross-device diversions. bleah.
+ [ -d /bin/secure-su ] || mkdir /bin/secure-su
+ chmod 700 /bin/secure-su
+ ln -sf ../../usr/doc/secure-su/README.gz /bin/secure-su/README.gz
+ dpkg-divert --package secure-su --add --rename \
+ --divert /bin/secure-su/su /bin/su
+ dpkg-divert --package secure-su --add --rename \
+ --divert /usr/man/man1/gnu-su.1.gz /usr/man/man1/su.1.gz
+fi
diff --git a/current/debian/securetty b/current/debian/securetty
new file mode 100644
index 00000000..d66d2a63
--- /dev/null
+++ b/current/debian/securetty
@@ -0,0 +1,14 @@
+# /etc/securetty: list of terminals on which root is allowed to login.
+# See securetty(5) and login(1).
+tty1
+tty2
+tty3
+tty4
+tty5
+tty6
+tty7
+tty8
+tty9
+tty10
+tty11
+tty12
diff --git a/current/debian/tar.c b/current/debian/tar.c
new file mode 100644
index 00000000..1f45eaa0
--- /dev/null
+++ b/current/debian/tar.c
@@ -0,0 +1,409 @@
+/*
+ * $Id: tar.c,v 1.2 1999/03/07 19:14:24 marekm Exp $
+ *
+ * This is a wrapper for tar to ensure that all files within the
+ * newly created tar archive have the owner and group set to
+ * root:root. This makes it possible to build Debian packages
+ * without root privileges (normally needed to chown files).
+ *
+ * Assumptions:
+ * - the directory containing this program is listed in $PATH
+ * before the directory containing the real tar program (/bin)
+ * - the options passed to tar cause it to output the archive
+ * (not compressed) on standard output
+ *
+ * Written by Marek Michalkiewicz <marekm@linux.org.pl>,
+ * public domain, no warranty, etc.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <fnmatch.h>
+#include <tar.h>
+
+#ifndef REAL_TAR
+#define REAL_TAR "/bin/tar"
+#endif
+
+#define RECORD_SIZE 512
+
+union record {
+ char data[RECORD_SIZE];
+ struct header {
+ char name[100]; /* NUL-terminated if NUL fits */
+ char mode[8]; /* 0+ spaces, 1-6 octal digits, space, NUL */
+ char uid[8]; /* format same as mode */
+ char gid[8]; /* format same as mode */
+ char size[12]; /* 0+ spaces, 1-11 octal digits, space */
+ /* if '1' <= typeflag <= '6', ignore size */
+ char mtime[12]; /* format same as size */
+ char chksum[8]; /* 0+ spaces, 1-6 octal digits, NUL, space */
+ char typeflag;
+ char linkname[100]; /* NUL-terminated if NUL fits */
+/* XXX - for GNU tar, magic is "ustar " (no NUL) and version is " \0" */
+ char magic[6]; /* must be TMAGIC (NUL term.) */
+ char version[2]; /* must be TVERSION */
+ char uname[32]; /* NUL-terminated */
+ char gname[32]; /* NUL-terminated */
+ char devmajor[8];
+ char devminor[8];
+#ifdef GNU_TAR_FORMAT
+ char atime[12];
+ char ctime[12];
+ char offset[12];
+ char longnames[4];
+ char pad;
+ struct sparse {
+ char offset[12];
+ char numbytes[12];
+ } sp[4];
+ char isextended;
+ char realsize[12];
+#else
+/* if prefix[0] != NUL then filename = prefix/name else filename = name */
+ char prefix[155]; /* NUL-terminated if NUL fits */
+#endif
+ } h;
+#ifdef GNU_TAR_FORMAT
+ struct exthdr {
+ struct sparse sp[21];
+ char isextended;
+ } xh;
+#endif
+};
+
+static union record tarbuf;
+static int infd = -1, outfd = -1;
+
+int main(int, char **);
+static ssize_t xread(int, char *, size_t);
+static ssize_t xwrite(int, const char *, size_t);
+static int block_is_eof(void);
+static void block_read(void);
+static void block_write(void);
+static void verify_magic(void);
+static void verify_checksum(void);
+static void update_checksum(void);
+static void set_owner(const char *);
+static void set_group(const char *);
+static void process_archive(void);
+
+
+int
+main(int argc, char **argv)
+{
+ int pipefd[2];
+ pid_t pid;
+ const char *real_tar;
+ int status;
+
+ real_tar = getenv("REAL_TAR");
+ if (!real_tar)
+ real_tar = REAL_TAR;
+ if (pipe(pipefd)) {
+ perror("pipe");
+ exit(1);
+ }
+ pid = fork();
+ if (pid == 0) { /* child */
+ /* redirect stdout to the pipe */
+ if (dup2(pipefd[1], STDOUT_FILENO) != 1) {
+ perror("dup2");
+ _exit(126);
+ }
+ close(pipefd[0]);
+ close(pipefd[1]);
+ /* run the real tar program */
+ execv(real_tar, argv);
+ if (errno == ENOENT) {
+ perror("execve");
+ _exit(127);
+ } else {
+ perror("execve");
+ _exit(126);
+ }
+ } else if (pid < 0) { /* error */
+ perror("fork");
+ exit(1);
+ }
+ /* parent */
+ close(pipefd[1]);
+ /* read from pipefd[0], modify tar headers, write to stdout ... */
+ infd = pipefd[0];
+ outfd = STDOUT_FILENO;
+ process_archive();
+ /* wait for the tar subprocess to finish, and return its exit status */
+ status = 1;
+ if (waitpid(pid, &status, 0) == -1) {
+ perror("waitpid");
+ exit(1);
+ }
+ if (WIFSIGNALED(status)) {
+ kill(getpid(), WTERMSIG(status));
+ exit(1);
+ }
+ exit(WEXITSTATUS(status));
+}
+
+/* EINTR-safe versions of read() and write() - they don't really help much
+ as GNU tar itself (version 1.11.8 at least) is not EINTR-safe, but it
+ doesn't hurt... Also, these functions never return errors - instead,
+ they print an error message to stderr, and exit(1). End of file is
+ indicated by returning the number of bytes actually read. */
+
+static ssize_t
+xread(int fd, char *buf, size_t count)
+{
+ ssize_t n;
+ size_t left;
+
+ left = count;
+ do {
+ n = read(fd, buf, left);
+ if ((n < 0) && (errno == EINTR))
+ continue;
+ if (n <= 0)
+ break;
+ left -= n;
+ buf += n;
+ } while (left > 0);
+ if (count > left)
+ return count - left;
+ if (n < 0) {
+ perror("read");
+ exit(1);
+ }
+ return 0;
+}
+
+
+static ssize_t
+xwrite(int fd, const char *buf, size_t count)
+{
+ ssize_t n;
+ size_t left;
+
+ left = count;
+ do {
+ n = write(fd, buf, left);
+ if (n < 0) {
+ if (errno == EINTR)
+ continue;
+ /* any other write errors are fatal */
+ perror("write");
+ exit(1);
+ }
+ left -= n;
+ buf += n;
+ } while (left > 0);
+ return count;
+}
+
+
+static int
+block_is_eof(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(tarbuf.data); i++) {
+ if (tarbuf.data[i])
+ return 0;
+ }
+ return 1;
+}
+
+
+static void
+block_read(void)
+{
+ ssize_t nread;
+
+ nread = xread(infd, tarbuf.data, RECORD_SIZE);
+ if (nread != RECORD_SIZE) {
+ fprintf(stderr, "unexpected end of file\n");
+ exit(1);
+ }
+}
+
+
+static void
+block_write(void)
+{
+ xwrite(outfd, tarbuf.data, RECORD_SIZE);
+}
+
+
+static void
+verify_magic(void)
+{
+ /* only check that magic starts with "ustar" - works for
+ standard UNIX tar as well as GNU tar formats. */
+ if (strncmp(tarbuf.h.magic, "ustar", 5) != 0) {
+ fprintf(stderr, "bad tar header magic\n");
+ exit(1);
+ }
+}
+
+
+static void
+verify_checksum(void)
+{
+ unsigned int i;
+ int csum;
+
+ if (sscanf(tarbuf.h.chksum, "%o", &csum) != 1) {
+ fprintf(stderr, "bad tar checksum format\n");
+ exit(1);
+ }
+ memset(tarbuf.h.chksum, ' ', sizeof(tarbuf.h.chksum));
+ for (i = 0; i < sizeof(tarbuf.data); i++)
+ csum -= (unsigned char) tarbuf.data[i];
+ if (csum) {
+ fprintf(stderr, "bad tar checksum value\n");
+ exit(1);
+ }
+}
+
+
+static void
+update_checksum(void)
+{
+ unsigned int i;
+ int csum;
+
+ memset(tarbuf.h.chksum, ' ', sizeof(tarbuf.h.chksum));
+ csum = 0;
+ for (i = 0; i < sizeof(tarbuf.data); i++)
+ csum += (unsigned char) tarbuf.data[i];
+ snprintf(tarbuf.h.chksum, sizeof(tarbuf.h.chksum), "%6o", csum);
+}
+
+
+static void
+set_owner(const char *username)
+{
+ const struct passwd *pw;
+
+ pw = getpwnam(username);
+ memset(tarbuf.h.uname, 0, sizeof(tarbuf.h.uname));
+ snprintf(tarbuf.h.uname, sizeof(tarbuf.h.uname), "%s", username);
+ snprintf(tarbuf.h.uid, sizeof(tarbuf.h.uid), "%6o ", (int) (pw ? pw->pw_uid : 0));
+}
+
+
+static void
+set_group(const char *groupname)
+{
+ const struct group *gr;
+
+ gr = getgrnam(groupname);
+ memset(tarbuf.h.gname, 0, sizeof(tarbuf.h.gname));
+ snprintf(tarbuf.h.gname, sizeof(tarbuf.h.gname), "%s", groupname);
+ snprintf(tarbuf.h.gid, sizeof(tarbuf.h.gid), "%6o ", (int) (gr ? gr->gr_gid : 0));
+}
+
+
+static void
+process_archive(void)
+{
+ ssize_t nread;
+ long size;
+
+ size = 0;
+ for (;;) {
+ /* read the header or data block */
+ block_read();
+ /* copy data blocks, if any */
+ if (size > 0) {
+ block_write();
+ size -= RECORD_SIZE;
+ continue;
+ }
+ if (block_is_eof()) {
+ /* eof marker */
+ block_write();
+ break;
+ }
+
+ verify_magic();
+ verify_checksum();
+
+ /* process the header */
+ switch (tarbuf.h.typeflag) {
+ case LNKTYPE:
+ case SYMTYPE:
+ case CHRTYPE:
+ case BLKTYPE:
+ case DIRTYPE:
+ case FIFOTYPE:
+ /* no data blocks - ignore size */
+ break;
+ case REGTYPE:
+ case AREGTYPE:
+ case CONTTYPE:
+ default:
+ if (sscanf(tarbuf.h.size, "%lo", &size) != 1) {
+ fprintf(stderr, "bad size format\n");
+ exit(1);
+ }
+ break;
+ }
+
+ /* XXX - for now, just chown all files to root:root. */
+ set_owner("root");
+ set_group("root");
+
+ update_checksum();
+ /* write the modified header */
+ block_write();
+ }
+ /* eof marker detected, copy anything beyond it */
+ for (;;) {
+ nread = xread(infd, tarbuf.data, RECORD_SIZE);
+ if (nread == 0)
+ break; /* end of file */
+ xwrite(outfd, tarbuf.data, (size_t) nread);
+ }
+}
+
+#if 0
+/* permission specification file format, fixperms-1.00 compatible:
+ type filename owner group mode [linkname | major minor] [# comment]
+
+ type:
+ - = regular file
+ l = link
+ d = directory
+ c = char dev
+ b = block dev
+ p = fifo
+ s = socket
+
+ filename - absolute pathname, wildcards ok [not for fixperms]
+ linkname - only for type l
+ major, minor - only for type c or b
+ owner group - numeric, or names [not for fixperms]
+
+ XXX not yet implemented
+*/
+
+struct permspec {
+ char *name;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+ char *uname;
+ char *gname;
+ char *linkname;
+ dev_t dev;
+ struct permspec *next;
+};
+#endif
diff --git a/current/doc/ANNOUNCE b/current/doc/ANNOUNCE
new file mode 100644
index 00000000..a19ad596
--- /dev/null
+++ b/current/doc/ANNOUNCE
@@ -0,0 +1,48 @@
+$Id: ANNOUNCE,v 1.4 2000/08/26 18:27:09 marekm Exp $
+
+[ This is the original comp.os.linux.announce posting (only the
+ author's name and e-mail address has been updated), kept here
+ for historical reasons. Many things have changed since then.
+ Linux distributions are using it, and the mailing list address
+ has been changed. See README.linux (in the same directory)
+ for more up to date information. --marekm ]
+
+This is a new beta release of the Shadow Password Suite for Linux.
+Many bugs have been reported (and fixed!), and the package is now
+under a BSD-style copyright. It was written by Julianne F. Haugh
+<jfh@austin.ibm.com>, and the Linux port is now maintained by me.
+
+Again, this is beta software which may still have some bugs, please
+treat it as such. Please don't install it if you don't know what
+you're doing. Please test it as much as you can, and report any
+bugs - if you report them, they will be fixed! If all goes well,
+Shadow should be stable enough for general use within a few months.
+Once it is stable, Linux distributions can start using it - there
+are no copyright problems anymore.
+
+Thanks to Greg Gallagher <ggallag@orion.it.luc.edu> there is now
+a developers mailing list, shadow-list@neptune.cin.net. Send the
+command "subscribe" to shadow-list-request@neptune.cin.net (NOT to
+the mailing list itself!) to subscribe if you are interested.
+
+
+LSM entry follows:
+
+Begin3
+Title: Shadow Password Suite
+Version: 3.3.3-951218
+Entered-date: 18DEC95
+Description:
+Keywords: login passwd security shadow
+Author: jfh@austin.ibm.com (Julie Haugh)
+Maintained-by: marekm@i17linuxb.ists.pwr.wroc.pl (Marek Michalkiewicz)
+Primary-site: sunsite.unc.edu /pub/Linux/system/Admin
+ 220K shadow-951218.tar.gz
+Alternate-site: ftp.ists.pwr.wroc.pl /pub/linux/shadow
+Original-site: ftp.uu.net ?
+Platforms:
+Copying-policy: BSD-like
+End
+
+Marek Michalkiewicz
+marekm@i17linuxb.ists.pwr.wroc.pl
diff --git a/current/doc/CHANGES b/current/doc/CHANGES
new file mode 100644
index 00000000..36d2ab10
--- /dev/null
+++ b/current/doc/CHANGES
@@ -0,0 +1,694 @@
+$Id: CHANGES,v 1.30 2000/09/02 18:40:42 marekm Exp $
+
+shadow-20000826 => shadow-20000902
+
+This is probably the last release from me.
+Tomasz Kloczko <kloczek@rudy.mif.pg.gda.pl> is the new maintainer.
+Good luck!
+
+(I'm still interested to know what is going on with this package,
+which is fairly important to many Linux distributions, so please
+Cc: marekm@linux.org.pl in any related discussions - just don't
+expect me to respond quickly...)
+
+Previous warning still applies - be careful!
+
+- applied some of the Red Hat patches (revised slightly), thanks to
+ Bernhard Rosenkraenzer <bero@redhat.de>: fix for truncated long
+ lines (>8K) in /etc/group, send SIGHUP to nscd (caching daemon
+ in glibc 2.1.x) after changing anything, add usermod -L and -U
+ options, remove LOG_CONS from openlog(), chage -d and -E handles
+ dates in yyyy-mm-dd format ('/' is not required)
+- various cleanups
+
+shadow-19990827 => shadow-20000826
+
+WARNING: this release is not tested (other than that it compiles for me),
+please be careful. Previous release was a year ago, so it is really time
+to release something and start looking for a new, better maintainer...
+(I've been extremely busy recently. Credit for most of the real work,
+such as complete PAM support, should go to Ben Collins <bcollins@debian.org>
+who maintains this package for Debian.)
+
+- merged most of the changes from Debian (not all of them yet, PAM support
+ should be complete but is not tested - need to upgrade to potato first)
+- added Polish translations of manual pages from PLD
+- change sulog() to not depend on global variables oldname, name
+- try to not follow symbolic links when deleting files recursively
+ in userdel (still not perfect, safest to do it in single user mode)
+- removed workarounds for ancient (pre-ANSI) C compilers - use gcc!
+ (a few ANSI C constructs were used already, and no one complained)
+- updated author's e-mail address (jfh@bga.com -> jfh@austin.ibm.com)
+
+shadow-19990709 => shadow-19990827
+
+- upgrade to autoconf-2.13, automake-1.4, libtool-1.3.3
+- i18n: added French translation by Vincent Renardias <vincent@ldsol.com>
+- i18n: added Swedish translation by Kristoffer Brånemyr <ztion@swipnet.se>
+- logoutd no longer reads /etc/logoutd.mesg at startup - instead, read
+ it when sending to luser's tty (no need to reload with SIGHUP)
+- added support for "usergroups" feature often found in Linux distributions
+ (if USERGROUPS_ENAB in login.defs set to "yes", uid != 0, uid == gid, and
+ username == groupname, then set umask to 002 instead of 022)
+- Debian: pwck and grpck are now run from a daily cron job (root will
+ receive an e-mail if something is wrong), and at system startup
+- added support for setting umask in /etc/limits
+- when using OPIE, re-prompt with echo on after empty password was entered
+- GETPASS_ASTERISKS now run time configurable (login.defs)
+- getpass() now uses stdin and stderr (not stdout) if it can't open /dev/tty
+- getpass() allows all input to be erased using Control-U, and beeps when
+ too many characters are entered
+- removed obsolete sgtty support, in 1999 everyone should have termios :)
+- Debian: tar wrapper no longer needed to build packages as non-root user
+ (install libtricks, and use "dpkg-buildpackage -rfakeroot" instead)
+- Debian: changes for GNU Hurd by Marcus Brinkmann <brinkmd@debian.org>:
+ dpkg-architecture, cross compilation, only build passwd, add
+ etc/login.defs.hurd conffile, conditionalize CBAUD
+- newgrp sets $HOME before running the new shell
+- both "sg group command" (usage message) and "sg group -c command"
+ (man page) work, updated both the usage message and the man page :)
+- i18n: added missing _() for some translatable strings
+
+shadow-19990607 => shadow-19990709
+
+- added PAM support to chfn and chsh (thanks to Thorsten Kukuk)
+- fixed a bug in newgrp if the user is in >= 17 groups
+- added @LIBSKEY@ to LDADD for all programs (for some reason,
+ almost all programs need it if skey/opie support is enabled)
+- changed grpconv/grpunconv to compile with --disable-shadowgrp
+- changed faillog to do something (assume -p) with no options specified
+- updated version of the udbachk passwd/shadow/group file integrity
+ checker (contrib/udbachk.v012.tgz)
+
+shadow-19990307 => shadow-19990607
+
+- upgraded to libtool-1.2, latest config.{guess,sub}
+- added missing #include "defines.h" in libmisc/login_desrpc.c - thanks
+ to almost everyone for reporting it :-)
+- moved PAM-related defines to pam_defs.h
+- added some braces to if/else to avoid egcs warnings
+- started adding PAM support to login (based on util-linux, not finished yet)
+- changed "!" to "x" for pw_passwd in src/newusers.c
+- a few more Y2K fixes
+- added contrib/udbachk.tgz (passwd/shadow/group file integrity checker),
+ thanks to Sami Kerola
+- Debian: made /etc/{limits,login.access,login.defs,porttime,securetty}
+ files all mode 0600 (Bug#38729 - login: /etc/limits is world readable)
+- updated mailing list information (moved again, now hosted by SuSE),
+ updated README.mirrors, other minor documentation updates
+- made getpass work with redirected stdin
+- new readpass echoing asterisks disabled by default by popular demand
+ (can be enabled at compile time: ./configure --enable-readpass)
+- the random number of asterisks in readpass is now more random
+ (random number generator initialization was missing)
+- commented out --enable-md5crypt (obsolete) in configure.in
+- when checking for libskey, link with -lcrypt if libcrypt is available
+ (otherwise the configure test for libskey fails - libskey needs libcrypt)
+- added Package/Version ident strings (so you can use the RCS "ident"
+ command to check any binary, which version of shadow it comes from)
+
+shadow-981228 => shadow-19990307
+
+- added support for setting process priority in /etc/limits
+- i18n: updated Greek translation
+- i18n: added Polish translation by Arkadiusz Miskiewicz
+- documented the -p option in useradd.8 and usermod.8 man pages
+- some "const" gcc warning fixes
+- attempt to fix lib/snprintf.c compilation problems
+- added restart/reload/force-reload to /etc/init.d/logoutd (found by lintian)
+- always require password for root logins (even with NO_PASSWORD_CONSOLE)
+- workaround for RedHat's CREATE_HOME feature in /etc/login.defs
+- changed to Y2K compatible version numbering
+- more Y2K fixes, use the ISO 8601 date format (yyyy-mm-dd) for default
+ values of user-entered dates (you can still enter dates in any format
+ supported by GNU date)
+- oops, added doc/README.nls to list of files to distribute
+- added missing sanitize_env() call to src/login.c
+- debian/rules installs /bin/login non-setuid by default, just in case...
+- build Debian packages with cracklib support (depends on cracklib-runtime)
+
+shadow-980724 => shadow-981228
+
+- login now clears the username in argv[] (in case someone types the
+ password instead of username, by mistake)
+- i18n support, Greek translation (Nikos Mavroyanopoulos), see README.nls
+- updated author's e-mail address (jfh@tab.com -> jfh@bga.com)
+- new getpass() replacement that displays *'s (Pavel Machek)
+- no password required when logging in from ttys listed under
+ NO_PASSWORD_CONSOLE in login.defs (Pavel Machek)
+- fixed limits code so RLIMIT_AS should work
+- upgraded to Debian 2.0
+- built a new machine (P2 350MHz, 64MB RAM) so the thing can be compiled
+ in reasonable time again
+- upgraded to automake-1.3, libtool-1.0h (also new config.guess and
+ config.sub that work on i686)
+- usermod fixed to handle group names starting with digits (not recommended)
+
+shadow-980626 => shadow-980724
+
+- security: login no longer gives you a root shell if setgid()
+ or initgroups() or setuid() fails for any reason, discovered
+ by Ted Hickman <thickman@sy.net>
+- remove libshadow.so -> libshadow.so.x.x symlink after install
+- a few int -> uid_t type cleanups
+- fail immediately (don't retry) in *_lock() if euid != 0
+- added sample PAM config files etc/pam.d/{passwd,su}
+- preliminary PAM support in su (untested - use at your own risk,
+ comments and patches welcome!)
+- cleanup and more comments in OPIE code (Algis Rudys)
+- added support for TCFS (Transparent Cryptographic File System)
+ (use ./configure --with-libtcfs, see http://tcfs.dia.unisa.it/
+ for more info), thanks to Aniello Del Sorbo
+
+shadow-980529 => shadow-980626
+
+- fixed bug in commonio_lock() (infinite recursion if lckpwdf() not
+ used and database cannot be locked), thanks to Jonathan Hankins
+- fixed bug in copy_tree() (NUL-terminate readlink() results),
+ thanks to Lutz Schwalowsky
+- no need to press Enter after Ctrl-C to interrupt password prompt
+- removed a few harmless gcc warnings
+- secure RPC login disabled if <rpc/key_prot.h> not found (glibc 2.0)
+- faillog.8: changed /usr/adm -> /var/log
+- pwconv.8: documented that it may fail on invalid password files
+
+shadow-980417 => shadow-980529
+
+- fixed "interesting" strzero() bug introduced by me in 980417:
+ strzero(cp) didn't work as intended (the macro used a local
+ variable called "cp" - oops...); Leonard N. Zubkoff was the
+ first person to report it - thanks!
+- fixed usermod -e to accept empty argument (like useradd),
+ thanks to Martin Bene
+- several changes from Debian 980403-0.2, see debian/changelog
+- added contrib/shadow-anonftp.patch (not yet merged, sorry...)
+ thanks to Calle Karlsson
+
+shadow-980403 => shadow-980417
+
+- fixed login session limits (again - broken since 980130)
+- more symbolic constants for exit status values
+- fixed logoutd to work with 8-character usernames in utmp
+ (no room for terminating NUL!)
+- various fixes to make the code more glibc2-friendly
+- updated doc/cracklib26.diff (fix for empty gecos, etc.)
+- updated the files in redhat/ from shadow-utils-970616-11.src.rpm
+ (RH 5.0 updates)
+
+shadow-980130 => shadow-980403
+
+- security: su now creates the sulog file (if enabled and doesn't
+ already exist) with umask 077
+- hopefully removed arbitrary group size limits (not yet for
+ shadow groups though - sgetsgent() still needs a rewrite,
+ but I don't want to delay this release any longer...)
+- fixed NULL dereference in groupmod -n
+
+shadow-971215 => shadow-980130
+
+- Debian binary packages can be built without root privileges
+ (tar wrapper - debian/tar.c)
+- new subdir "redhat" (needs more work, see redhat/README)
+- in several places, exit(127) if exec fails with ENOENT, and
+ exit(126) on other errors (as in ksh and bash)
+- renamed getpass() and md5_crypt() to libshadow_* to avoid name
+ conflicts with libc functions - md5_crypt() is also in libcrypt.a
+ on Linux/PPC, thanks to Anton Gluck <gluc@midway.uchicago.edu>
+- handle crypt() returning NULL (possible according to Single Unix
+ Spec) more gracefully (exit instead of SIGSEGV)
+- fixed bug in putgrent() that showed up when realloc() moved the
+ buffer while expanding it, thanks to Floody <flood@evcom.net>
+- fixed bug in login session limits (with a limit set to N logins,
+ only N-1 logins were allowed), thanks to Floody <flood@evcom.net>
+- upgraded to libtool-1.0h (now recognizes GNU ld on Debian 1.3.1)
+- newer config.guess and config.sub (should work on x86 for x > 5)
+- removed doc/automake-1.0.diff (obsoleted by automake-1.2)
+- added doc/cracklib26.diff (some patches for cracklib-2.6)
+- documented more (not all yet) login.defs(5) settings
+- replaced more exit status numeric values with #defines
+- shadow-utils.spec now generated from shadow-utils.spec.in
+ (so I don't have to edit version numbers for every new release)
+- groupadd -f option, based on RedHat's shadow-utils-970616-9 patch
+ ("force" - exit(0) if the group already exists); other RedHat-
+ specific options not added yet (best done in a perl script that
+ runs useradd/usermod/groupadd - see Debian's adduser-3.x)
+- added -O option (override login.defs values) to useradd and groupadd
+- if usermod can't update the group file(s), exit(10) but update the
+ password file(s) anyway (as documented by Solaris man page)
+- useradd should no longer set sp_expire to the current date (oops)
+- configure.in: added --enable-desrpc, check for gethostbyname in libc
+ before trying libnsl (necessary for Solaris; not for Linux or Irix,
+ even though libnsl may be present), fixed pw_age/pw_comment/pw_quota
+ detection, setpgrp vs. setpgid, other minor tweaks
+- various */Makefile.am tweaks
+- login.defs: added FAKE_SHELL - program to run instead of the login
+ shell, with the real shell in argv[0] (Frank Denis)
+- login.defs: ignore case in yes/no settings
+- more E_* defines instead of hardcoded numbers for exit()
+- added sanitize_env() for setuid programs
+- login_desrpc() checks for getnetname() errors
+- new password is not "too similar" if it is long enough
+- replacement strstr() was static, no one noticed :-)
+- {pw,spw}_lock() and {pw,spw}_unlock() track the lock count and call
+ lckpwdf() and ulckpwdf() as needed, *_lock_first() hack removed
+- login sets $REMOTEHOST for remote logins
+- added newgrp -l option (Single Unix Spec, same as "-")
+- EXPERIMENTAL shared lib support using libtool (libshadow.so saves about
+ 200K of disk space on Linux/x86), enabled by default if supported by
+ the system, use ./configure --disable-shared if it causes any problems.
+ Warning: libshadow.so is intended for internal use by this package
+ only - binary compatibility with future releases is not guaranteed.
+ There should be no need to link any other programs with libshadow.so -
+ the libshadow.so -> libshadow.so.x.x symlink is unnecessary.
+- pam_strerror() takes one or two arguments, depending on the Linux-PAM
+ version (!) - added check to configure; fixed do_pam_passwd prototype
+- libmisc/login_access.c should compile on Linux/PPC and Solaris
+- added information about the new ftp site to doc/README.mirrors
+
+shadow-971001 => shadow-971215
+
+- added workaround for NYS libc 5.3.12 (RedHat 4.2) bug to grpck
+- updated the RPM .spec file
+- renamed rlogin() to do_rlogin() to avoid Linux/PPC build problem
+ (glibc defines something else named "rlogin" in utmpbits.h ?)
+- added MD5 checksums in Debian packages
+- added -p and -g options to vipw (edit the password or group file
+ respectively, regardless of the command name in argv[0])
+- removed old DBM support (NDBM code is still there)
+- fixed a bug in gpasswd: current username was incorrectly identified as
+ "root" because of setuid(0) done too early. It may be a security hole
+ when using shadow groups - if "root" is listed as a group administrator,
+ any user can add/remove members in that group. Thanks to Jesse Thilo.
+- gpasswd now logs which user (root or group admin) made the changes
+- passwd now uses $PATH to search for the chfn, chsh, gpasswd commands
+- newgrp and add_groups() allocate supplementary group lists dynamically
+- moved check_shell() from src/chsh.c to libmisc/chkshell.c
+- CHFN_RESTRICT in login.defs can now specify exactly which fields may be
+ changed by regular users (any combination of letters "frwh")
+- fixed contrib/pwdauth.c segfault with non-existent usernames
+- minor change in lib/getdef.c to handle quotes better (Juergen Heinzl)
+- new date parsing code (from GNU date) used by useradd, usermod, chage
+- upgraded to automake-1.2, added libtool-0.7 (no libshadow.so yet)
+- converted code to ANSI C, added ansi2knr (untested - use gcc!)
+- fixed useradd -G segfault (one '*' that shouldn't be there)
+- allow 8-bit characters in chfn
+- added support for RLIMIT_AS (max address space) in libmisc/limits.c
+- changed the handling of NIS plus entries in password files
+- some more tweaking in various debian/* files
+- logoutd uses getutent() instead of reading utmp file directly
+- fixed lckpwdf() called twice (and failing) when changing password
+ if the user is not listed in /etc/shadow (Mike Pakovic)
+- erase and kill characters left unchanged if not defined in login.defs
+
+shadow-970616 => shadow-971001
+
+- Debian: mkpasswd no longer installed (dbm files not supported)
+- chpasswd checks for shadow/non-shadow at run time, too
+- added chpasswd -e (input file with encrypted passwords) - Jay Soffian
+- changed libmisc/login_access.c as suggested by Dave Hagewood
+- replaced sprintf() with snprintf() in several places
+- added lib/snprintf.[ch] (from XFree86) for systems without snprintf()
+- minor tweaks in contrib/adduser.c (/usr/local -> /usr)
+- non-root users can only run su with a terminal on stdin
+- temporarily disabled DES_RPC because getsecretkey() causes login to hang
+ for 5 minutes on at least one RH 4.0 system. Not sure if this is a bug
+ in libc, or system misconfiguration. Needs further investigation.
+- check for strerror() and -lrpcsvc (should compile on SunOS again)
+- fixed free() called twice in libmisc/mail.c
+- added information about mirror sites (doc/README.mirrors)
+- updated pwconv.8 and pwunconv.8 man pages
+- "make install" now installs pwconv, pwunconv, grpconv, grpunconv
+- pwauth.8 no longer installed (AUTH_METHODS not supported by default)
+- corrected su.1 man page ($SHELL not used)
+- no need for --with-md5crypt if the MD5-based crypt() is already in libc
+ (or another library specified in /etc/ld.so.preload - Linux ld.so 1.8.0+)
+- cleaned up PASS_MAX in getpass() (127 always assumed)
+- default editor for vipw changed from /bin/ae to a real editor :)
+
+shadow-970601 => shadow-970616
+
+- fixed execlp call (missing NULL) in src/vipw.c
+- vipw now preserves permissions on edited files
+- commented out the xdm-shadow hack in shadowconfig
+- improved RedHat spec file (Timo Karjalainen)
+- updated mailing list information
+- added information about the shadow paper (doc/README.shadow-paper)
+- renamed doc/console.c.spec (confused RPM)
+
+shadow-970502-2 => shadow-970601
+
+- fixed a typo in libmisc/mail.c causing login to segfault
+ if MAIL_CHECK_ENAB=yes (sorry!)
+- patches for OPIE support (Algis Rudys) (untested)
+- programs that modify /etc/passwd or /etc/shadow will use
+ lckpwdf() if available
+- now compiles with PAM support! (still untested)
+- cosmetic error message changes (prefixed by argv[0]:)
+
+shadow-970216 => shadow-970502-2
+
+- shadow group support fixes (grpconv didn't work - for some
+ reason, putsgent() returns 1 instead of 0 on success;
+ now -1 = failure, anything else = success)
+- upgraded to autoconf-2.12
+- pwconv and pwunconv now follow other UN*X systems and SVID3
+ (modify files in place), original versions moved to "old"
+- scologin.c moved to "old" (it was only for SCO Xenix) so
+ people stop sending patches for scologin.c gcc warnings :)
+- don't use the MD5* functions in libmisc/salt.c (glibc has
+ the new md5 crypt(), but no <md5.h> and MD5* functions!)
+- support for MkLinux, Solaris, JIS, Qmail (Frank Denis)
+- "passwd -S -a" now really works
+- support for Debian, vipw, a few fixes (Guy Maor)
+- src/login.c radius bug fix (Rafal Maszkowski)
+- ISSUE_FILE_ENAB -> ISSUE_FILE in the sample /etc/login.defs
+- fixes for glibc and DES_RPC (Thorsten Kukuk)
+- limits.5 man page (Luca Berra)
+- expiry will work setgid shadow too, removed euid 0 check
+- added check for a64l() to configure (glibc)
+
+shadow-961025 => shadow-970216
+
+- major rewrite of *io.c (no more 4 copies of almost identical code)
+- use fsync() (if available) instead of sync() when updating password files
+- use fchmod() and fchown() if available
+- keep the NIS "plus on a line by itself" entries at end of passwd/group
+- configure checks location of passwd/chfn/chsh programs (/usr/bin or /bin)
+- passwd -S -a: list information about all users (root only)
+- passwd -k: change only expired passwords
+- passwd -q: quiet mode
+- first attempt at PAM support in passwd
+- passwd updates the non-shadow password if /etc/shadow exists but the
+ user has no shadow password
+- passwd logs who changed the password, added hook to allow non-root
+ administrators who can change passwords (not implemented yet)
+- su sets $HOME even without the "-" option (suggested by Joey Hess)
+- added -p (set encrypted password) option to useradd and usermod
+ (idea from hpux10 - undocumented option used internally by SAM)
+- useradd -D -e does the right thing (set default expiration date)
+- USERDEL_CMD in login.defs instead of hardcoded {ATRM,CRONTAB}_COMMAND
+ because there are just too many systems that need different commands
+- removed #ifdef FAILLOG_LOCKTIME (now always enabled), warning: the
+ faillog file format has been changed (somewhere between 960129 and
+ 960810), please truncate the old file (if any) to zero length
+- ISSUE_FILE (may be different from /etc/issue) instead of ISSUE_FILE_ENAB
+- wtmp, lastlog, faillog file location guessed by configure
+- separate checks for invalid user and group names, max username length
+ based on struct utmp (it's not always 8 characters)
+- pwck and grpck now check for invalid user/group names
+- pwck -q (quiet, report only serious problems) option added
+- separate cleaner sgetpwent() without the NIS magic
+- NIS entries ignored (never changed) by *io.c, pwck, grpck
+- various code cleanups
+- new get_my_pwent() function for getting my own username, uid etc.
+- faillog opens the file read-write if possible (even if not root)
+- passwd -S allowed for normal users (for their own uid only)
+- handle the case of login denied to passwordless accounts better
+ ("Login incorrect" without "Password:" prompt looks strange)
+- corrected author information and removed a copyright restriction
+
+shadow-960925 => shadow-961025
+
+- fixed a few typos in shadow group code
+- don't check for names starting with 'r' to determine if the shell
+ is restricted, use /etc/shells instead (for the "rc" shell)
+- removed extra definition of LASTLOG_FILE in configure.in
+- expiry no longer segfaults if no /etc/shadow
+- userdel -r "can't remove mailbox" warning no longer printed on success
+- useradd exit codes changed to match hpux10 man page
+- fixed possible fd leak etc. in file locking code (lib/commonio.c)
+
+shadow-960920 => shadow-960925
+
+- bug fixes to the new environment code using malloc
+- use hardcoded names instead of basename(argv[0]) for openlog() in programs
+ that users can run (chage, chfn, chsh, gpasswd, login, newgrp, passwd, su)
+- small fix to isexpired(), and use it in passwd as well
+- use strftime() and strptime() if available
+- added chmod 600 /etc/passwd- at the end of pwconv5 (backup file may
+ contain encrypted passwords!)
+- pass size to change_field (chage, chfn, chsh) instead of assuming BUFSIZ
+ (nothing bad happened yet, just a cleanup)
+- gpasswd should work with both shadow and non-shadow group passwords
+- detect unsupported options if no shadow (gpasswd, useradd, usermod)
+- passwd -e for sunos4 (ATT_AGE), untested
+- read environment from file (ENVIRON_FILE in login.defs), idea from ssh
+- small fix to l64a()
+- passwd prints a message after password successfully changed (for things
+ like poppassd which run passwd and expect some output)
+- passwd logs if password was changed by root (as opposed to a luser)
+- passwd uses current uid if no username argument and getlogin() fails
+
+shadow-960910 => shadow-960920
+
+- use malloc for environment variables, no more MAXENV (Juergen Heinzl)
+- newusers should work with both shadow and non-shadow passwords
+ (still left to do: chpasswd, gpasswd)
+- login-static no longer compiled by default
+- more SYSLOG() macros
+
+shadow-960810 => shadow-960910
+
+- updated README.linux to point to the new ftp site
+- chfn and chsh optionally (CHFN_AUTH) prompt for password like util-linux
+- man pages now closer to LDP standards (Ivan Nejgebauer)
+- newgrp uses SYSLOG_SG_ENAB (not SU) as in the /etc/login.defs comments
+- obscure.c fixed to compile with HAVE_LIBCRACK
+- cosmetic message changes in age.c
+- utmp open error check fixed in utmp.c
+- grpunconv added (Michael Meskes)
+- login reports invalid login time, not "Login incorrect" (Ivan Nejgebauer)
+- logoutd sets OPOST before writing to the tty (Ivan Nejgebauer)
+- sulogin: don't use syslog(), other minor changes (Ivan Nejgebauer)
+- passwords can be changed if sp_max == -1 (now considered infinity)
+- usermod: don't use sizeof(struct lastlog) when writing to faillog (ugh)
+- started replacing lots of #ifdef USE_SYSLOG with cleaner macros
+- contrib/rpasswd.c added (Joshua Cowan)
+- PASS_MAX is 127 with MD5_CRYPT (not just for Linux - sunos4 too...)
+- workarounds for a RedHat NYS libc getspnam() bug (if /etc/shadow
+ doesn't exist, it succeeds and returns sp_lstchg==0 instead of -1).
+
+shadow-960129 => shadow-960810
+
+- automake, configure checks for libcrypt and libcrack (Janos Farkas)
+- added --enable-shadowgrp to configure (shadow groups disabled by default)
+- should compile on SunOS 4.1.x - but it does NOT mean that it works :-)
+- login sets HUSHLOGIN=TRUE or FALSE (for shell startup scripts etc.)
+- hopefully removed all the rcsid warnings
+- contrib/atudel perl script to remove at jobs (thanks to Brian Gaeke)
+- resource limits (Cristian Gafton)
+- workaround for buggy init/getty(?) leaving junk in ut_host on RedHat
+- more fixes in man pages
+- pwck and grpck no longer suggest to run mkpasswd if *DBM not compiled in
+- most programs (groupadd, groupdel, groupmod, grpck, login, passwd, pwck,
+ su, useradd, userdel, usermod) should now work with both shadow and
+ non-shadow passwords/groups (check for /etc/shadow and /etc/gshadow at
+ run time); a few programs still left to do
+- mailbox mv/chown/rm in usermod/userdel (suggested by Cristian Gafton)
+- new contrib/adduser.c from Chris Evans
+- lots of other minor changes
+- source tree reorganization, GNU autoconf, portability cleanups
+- basename() renamed to Basename() to avoid name space confusion
+- new programs to create /etc/shadow and /etc/gshadow: pwconv5, grpconv
+- newgrp cleanup and a few fixes
+- useradd uses PASS_MAX_DAYS, PASS_MIN_DAYS and PASS_WARN_AGE
+- don't make the first group member the group admin by default
+ (define FIRST_MEMBER_IS_ADMIN to get the old gpasswd behaviour)
+- password aging constants, NGROUPS_MAX and syslog stuff in only one
+ place (defines.h) instead of repeating it in all source files...
+- added userdel -r safety check (refuse to remove the home directory
+ if it would result in removing some other user's home directory)
+- usermod -u now correctly checks for non-unique uid (unless -o)
+- sync() after updating password files, just to be more safe
+- "make install" should install /etc/login.defs if it doesn't exist
+- new option to control what happens if we can't cd to the home directory
+ (DEFAULT_HOME in /etc/login.defs)
+- enter the home directory as the user, not as root (for NFS etc.)
+- added check for Slackware bugs (nobody UID -1) in pwck and grpck
+- new CONSOLE_GROUPS feature (thanks to pacman@tardis.mars.net), it is
+ possible to add specified groups (floppy etc.) for console logins
+- new faillog feature: lock account for specified (per-user) time since
+ the last failure after exceeding the failure limit
+- new man pages (gpasswd.1, login.access.5, suauth.5)
+- fixes in man pages, renamed *.4 to *.5
+- new "contrib" directory (two adduser programs)
+- changed some "system" to "feature" #ifdefs (autoconf someday...)
+- sulogin no longer requires to be run from init, should work from rc
+ scripts too
+- changes to prevent unshadowing with libc SHADOW_COMPAT (get info
+ using xx_locate(), modify it and call xx_update(), don't write back
+ anything returned by getpwnam() etc.)
+- stupid bug fixed in lastlog.c
+- don't move non-directories in "usermod -m"
+- don't log unknown usernames (passwords mistyped for usernames) (lmain.c)
+- macros to get around ancient compilers which don't like prototypes
+- make more use of "const" (not everywhere yet)
+- added #ifdef AUTH_METHODS - very few people use administrator defined
+ authentication methods because many programs are not aware of them;
+ not supporting them makes the code simpler
+- new "save" and "restore" Makefile targets, thanks to Rafal Maszkowski
+- sgetgrent() in libshadow.a is optional, some versions of libc have it,
+ see HAVE_SGETGRENT in config.h (grent.c)
+- don't use continued lines in /etc/group, the standard getgr*() functions
+ don't support that (grent.c)
+- removed the third main() argument (according to libc docs, not allowed by
+ POSIX.1 - use environ instead) (lmain.c, smain.c, newgrp.c, sulogin.c)
+- login access control (lmain.c, login_access.c)
+- added copyright notice to login_access.c (from logdaemon-5.0)
+- detailed su access control (smain.c, suauth.c) - thanks to Chris Evans
+- added closelog() in su before executing the shell (smain.c)
+- getting current user name changed (smain.c)
+- "x" instead of "*" in pw_passwd, consistent with pwconv (useradd.c)
+- getpass() shouldn't return NULL except on errors (getpass.c)
+- moved isexpired() to isexpired.c (now part of libshadow.a) from age.c
+- SunOS4-like passwd -e (force change on next login) (isexpired.c, passwd.c)
+- can use shadow support in new versions of Linux libc instead of libshadow.a,
+ see HAVE_SHADOWPWD, HAVE_SHADOWGRP in config.h.linux (shadow.c, gshadow.c)
+- "no shadow password" not logged, the same /bin/login should work with both
+ shadow and non-shadow passwords (lmain.c)
+- some cleanup in various places (lmain.c, passwd.c)
+- new program to verify username/password pairs, for xlock etc.; it is not
+ installed by default, read the comments first (pwdauth.c)
+- authentication programs run with empty environment for safety (pwauth.c)
+- added missing fstat error checks (faillog.c, lastlog.c, setup.c, *io.c)
+- common code separated from *io.c (commonio.c)
+- ownership and permissions on password files are now preserved (we may try
+ to make more use of setgid and setuid non-root programs in the future)
+- added (untested) MD5-based crypt() from FreeBSD (md5crypt.c), see
+ MD5_CRYPT in config.h.linux and MD5_CRYPT_ENAB in login.defs.linux
+- termios/termio/sgtty macros cleaned up a bit
+
+shadow-951218 => shadow-960129
+
+Emergency bug fix release - no new features since 951218. There are many
+new changes, but this bug really can't wait until they are tested.
+
+Probably all previous versions of the shadow suite have a serious bug which
+makes it possible to overwrite the stack by entering very long username at
+the login prompt. This can give root access to any remote user!
+
+Changed the maximum size in login.c from BUFSIZ (1024) to 32 (to match
+size of the array in lmain.c). Aaargh!!!
+
+shadow-951203 => shadow-951218
+
+Changes:
+- Linux utmp handling fixes (utmp.c)
+- last failure date printing fixes (failure.c)
+- minor fix to compile with USE_CRACKLIB (obscure.c)
+- eliminated the use of snprintf (env.c, lmain.c, login.c, shell.c, smain.c)
+- basename.c added, replacing duplicated code in various places
+- "su -" runs the shell with '-' in argv[0] again (smain.c)
+- removing at/cron jobs cleaned up (userdel.c)
+- /etc/gshadow should not be world-readable (sgroupio.c)
+- if fflush() failed, files were not closed (*io.c)
+- login prompt is now "hostname login: " on Linux (lmain.c, login.c)
+- "save" and "restore" targets commented out (don't work) (Makefile.linux)
+- some minor cleanups for gcc -Wall (unused variables etc.)
+- removed README.FIRST (copyrights are OK now)
+- updated ANNOUNCE, README.linux, WISHLIST
+- as suggested, converted to RCS
+
+shadow-3.3.2-951127 => shadow-951203-jfh
+
+Changes:
+- Added the BSD-style copyright to all of the files. Any files with the
+ old copyright have multiple copyright holders and need to be cleanroomed
+ to produce BSD-style copyrightable files, or I need to get the consent
+ of the others to change the copyright.
+- Changed the ANNOUNCE file to not refer to the README.FIRST file. Now
+ that all of the files should have the correct copyright there is no need
+ to refer to that e-mail message.
+- Changes SCCS strings to "%W% %U% %G%". Marek needs to either convert to
+ RCS or check into SCCS and then checkout. I'd suggest using RCS ;-)
+
+ jfh@rpp386.cactus.org
+
+shadow-3.3.2-951106 => shadow-951127
+
+Note: for now this code only supports Linux. All the #ifdef's are there
+(and will be; support for at least SunOS 4.1.x would be nice) but:
+- I had to fix some potential security problems resulting from sloppy
+ coding (no bounds checking), and it was easier for me to use snprintf()
+ (not available on many systems, unfortunately), I'll fix that later.
+ Old versions of Linux libc don't have snprintf() either, and the one
+ in libbsd.a ignores the max size - don't use it! (libc-4.6.27 is OK)
+- I am lazy and only updated Makefile.linux and config.h.linux this time
+- I don't have root access to non-Linux systems (this means no testing)
+- this code needs some major reorganization, which will (hopefully)
+ make porting easier
+
+Changes:
+- some code cleanup, prototypes.h, defines.h, Makefile and config.h changes
+- login can be statically linked (not that I think it's a good idea, better
+ fix the telnetd, but paranoid people will like it :-)
+- login is installed non-setuid by default
+- check for NULL from getpass()
+- wipe cleartext password from getpass() when no longer needed (pwauth.c)
+- use standard "Password: " prompt by default (pwauth.c)
+- hopefully fixed bogus sigaction() stuff (Linux only) (getpass.c)
+- oops, setrlimit wants bytes, ulimit wants 512-byte units (lmain.c)
+- Linux has <lastlog.h>
+- print ll_host on Linux too (lmain.c)
+- size checking in various places (setuid root programs, argh!)
+- preserve TERM from getty (lmain.c)
+- don't ignore SIGHUP (lmain.c)
+- :%s/setenv/set_env/g (setenv(3) conflict) (env.c, lmain.c, login.c)
+- remove LD_xxx (env.c)
+- use bzero() instead of memset() for BSD portability and less #ifdef's
+ (if the system has no bzero(), implement it as a macro using memset())
+- the above fixes wrong order of memset() parameters (log.c)
+- use getutent/pututline instead of doing it by hand (utmp.c)
+- added the new settings to login.defs.linux
+- added login_access.c to the distribution (not used yet)
+
+==========
+
+shadow-3.3.2 => shadow-3.3.2-951106
+
+- added dummy pad.c and #ifdef'ed out references to pad_auth (pwauth.c)
+- malloc/strdup error checking, hopefully no more core dumps...
+- define HAVE_RLIMIT instead of HAVE_ULIMIT for Linux (config.h.linux)
+- changed pathnames on Linux to conform to new FSSTND (/var/log etc.)
+- larger buffer for cipher, for md5 crypt() if and when (encrypt.c, passwd.c)
+- use POSIX termios whenever possible on Linux
+- list.c, removed add_list/del_list from gpmain.c, user{add,del,mod}.c
+- strtoday.c, removed duplicates from chage.c, useradd.c, usermod.c
+- login -h only for root (lmain.c)
+- login -r not needed for Linux (lmain.c)
+- sample login.defs modified for Linux (login.defs.linux)
+- swapped chfn USAGE and ADMUSAGE (chfn.c)
+- added -u to passwd usage (passwd.c)
+- no #! check necessary for Linux (shell.c)
+- define OLD_CRON for some old incompatible Linux distributions (userdel.c)
+- PASS_MAX is now 127 (not 8) for Linux (getpass.c)
+- LOGIN_RETRIES, LOGIN_TIMEOUT, PASS_CHANGE_TRIES are no longer compiled in,
+ can now be set in login.defs, old values are used as defaults (lmain.c)
+- unique uid/gid selection now more robust (useradd.c, groupadd.c)
+- UID_MIN, UID_MAX, GID_MIN, GID_MAX in login.defs (useradd.c, groupadd.c)
+- CRACKLIB_DICTPATH no longer compiled in, can be set in login.defs (passwd.c)
+- PASS_ALWAYS_WARN: warn about weak passwords even for root (passwd.c)
+- PASS_MAX_LEN, check truncated passwords again (obscure.c)
+- check for weak passwords too if previous password was empty (obscure.c)
+- CHFN_RESTRICT: don't let users change their full names (chfn.c)
+- Linux has getusershell(), use it (chsh.c)
+- check if the new shell is executable by the user (chsh.c)
+- sleep before printing "Login incorrect", not the other way around (lmain.c)
+- don't be picky about utmp only if any of -rfh flags given (lmain.c)
+- do "wheel group" more like BSD does (smain.c)
+- use getlogin() in su (smain.c)
+- UMASK from login.defs defaults to 077, not 0 (lmain.c, newusers.c)
+- #undef HAS_ATRM for Linux until atrm can do what we need (config.h.linux)
+- Linux has most commands in /usr/bin, not /bin (age.c, passwd.c, userdel.c)
+- ULIMIT from login.defs works on systems using setrlimit() too (lmain.c)
+- LOGIN_STRING should work now (pwauth.c, getdef.c)
+- kludge to avoid conflict with Linux <shadow.h> (gshadow.h)
+- mv Makefile Makefile.xenix ; mv config.h config.h.xenix - so that they are
+ not lost when you copy the right ones to Makefile and config.h
+
+==========
+
+shadow-3.3.2
+
+Original version, received directly from the author.
+
diff --git a/current/doc/HOWTO b/current/doc/HOWTO
new file mode 100644
index 00000000..01a90ed4
--- /dev/null
+++ b/current/doc/HOWTO
@@ -0,0 +1,1918 @@
+[ Note: the installation instructions in this document are somewhat
+ out of date - the package now uses GNU autoconf and is configured
+ just like most GNU packages: run ./configure then make. --marekm ]
+
+ Linux Shadow Password HOWTO
+ Michael H. Jackson, mhjack@tscnet.com
+ v1.3, 3 April 1996
+
+ This document aims to describe how to obtain, install, and configure
+ the Linux password Shadow Suite. It also discusses obtaining, and
+ reinstalling other software and network daemons that require access to
+ user passwords. This other software is not actually part of the
+ Shadow Suite, but these programs will need to be recompiled to support
+ the Shadow Suite. This document also contains a programming example
+ for adding shadow support to a program. Answers to some of the more
+ frequently asked questions are included near the end of this document.
+
+ 1. Introduction.
+
+ This is the Linux Shadow-Password-HOWTO. This document describes why
+ and how to add shadow password support on a Linux system. Some
+ examples of how to use some of the Shadow Suite's features is also
+ included.
+
+ When installing the Shadow Suite and when using many of the utility
+ programs, you must be logged in as root. When installing the Shadow
+ Suite you will be making changes to system software, and it is highly
+ recommended that you make backup copies of programs as indicated. I
+ also recommend that you read and understand all the instructions
+ before you begin.
+
+ 1.1. Changes from the previous release.
+
+ Additions:
+ Added a sub-section on why you might not want to install shadow
+ Added a sub-section on updating the xdm program
+ Added a section on how to put Shadow Suite features to work
+ Added a section containing frequently asked questions
+
+ Corrections/Updates:
+ Corrected html references on Sunsite
+ Corrected section on wu-ftp to reflect adding -lshadow to the Makefile
+ Corrected minor spelling and verbiage errors
+ Changed section on wu-ftpd to support ELF
+ Updated to reflect security problems in various login programs
+ Updated to recommend the Linux Shadow Suite by Marek Michalkiewicz
+
+ 1.2. New versions of this document.
+
+ The latest released version of this document can always be retrieved
+ by anonymous FTP from:
+
+ sunsite.unc.edu
+
+ /pub/Linux/docs/HOWTO/Shadow-Password-HOWTO
+
+ or:
+
+ /pub/Linux/docs/HOWTO/other-formats/Shadow-Password-HOWTO{-html.tar,ps,dvi}.gz
+
+ or via the World Wide Web from the Linux Documentation Project Web
+ Server <http://sunsite.unc.edu/mdw/linux.html>, at page: Shadow-
+ Password-HOWTO <http://sunsite.unc.edu/linux/HOWTO/Shadow-Password-
+ HOWTO.html> or directly from me, <mhjack@tscnet.com>. It will also be
+ posted to the newsgroup: comp.os.linux.answers
+
+ This document is now packaged with the Shadow-YYDDMM packages.
+
+ 1.3. Feedback.
+
+ Please send any comments, updates, or suggestions to me: Michael H.
+ Jackson <mhjack@tscnet.com> The sooner I get feedback, the sooner I
+ can update and correct this document. If you find any problems with
+ it, please mail me directly as I very rarely stay up-to-date on the
+ newsgroups.
+
+ 2. Why shadow your passwd file?
+
+ By default, most current Linux distributions do not contain the Shadow
+ Suite installed. This includes Slackware 2.3, Slackware 3.0, and
+ other popular distributions. One of the reasons for this is that the
+ copyright notices in the original Shadow Suite were not clear on
+ redistribution if a fee was charged. Linux uses a GNU Copyright
+ (sometimes refereed to as a Copyleft) that allows people to package it
+ into a convenient package (like a CD-ROM distribution) and charge a
+ fee for it.
+
+ The current maintainer of the Shadow Suite, Marek Michalkiewicz
+ <marekm@i17linuxb.ists.pwr.wroc.pl> received the source code from the
+ original author under a BSD style copyright that allowed
+ redistribution. Now that the copyright issues are resolved, it is
+ expected that future distributions will contain password shadowing by
+ default. Until then, you will need to install it yourself.
+
+ If you installed your distribution from a CD-ROM, you may find that,
+ even though the distribution did not have the Shadow Suite installed,
+ some of the files you need to install the Shadow Suite may be on the
+ CD-ROM.
+
+ However, Shadow Suite versions 3.3.1, 3.3.1-2, and shadow-mk all have
+ security problems with their login program and several other suid root
+ programs that came with them, and should no longer be used.
+
+ All of the necessary files may be obtained via anonymous FTP or
+ through the World Wide Web.
+
+ On a Linux system without the Shadow Suite installed, user information
+ including passwords is stored in the /etc/passwd file. The password
+ is stored in an encrypted format. If you ask a cryptography expert,
+ however, he or she will tell you that the password is actually in an
+ encoded rather than encrypted format because when using crypt(3), the
+ text is set to null and the password is the key. Therefore, from here
+ on, I will use the term encoded in this document.
+
+ The algorithm used to encode the password field is technically
+ referred to as a one way hash function. This is an algorithm that is
+ easy to compute in one direction, but very difficult to calculate in
+ the reverse direction. More about the actual algorithm used can be
+ found in section 2.4 or your crypt(3) manual page.
+
+ When a user picks or is assigned a password, it is encoded with a
+ randomly generated value called the salt. This means that any
+ particular password could be stored in 4096 different ways. The salt
+ value is then stored with the encoded password.
+
+ When a user logs in and supplies a password, the salt is first
+ retrieved from the stored encoded password. Then the supplied
+ password is encoded with the salt value, and then compared with the
+ encoded password. If there is a match, then the user is
+ authenticated.
+
+ It is computationally difficult (but not impossible) to take a
+ randomly encoded password and recover the original password. However,
+ on any system with more than just a few users, at least some of the
+ passwords will be common words (or simple variations of common words).
+
+ System crackers know all this, and will simply encrypt a dictionary of
+ words and common passwords using all possible 4096 salt values. Then
+ they will compare the encoded passwords in your /etc/passwd file with
+ their database. Once they have found a match, they have the password
+ for another account. This is referred to as a dictionary attack, and
+ is one of the most common methods for gaining or expanding
+ unauthorized access to a system.
+
+ If you think about it, an 8 character password encodes to 4096 * 13
+ character strings. So a dictionary of say 400,000 common words,
+ names, passwords, and simple variations would easily fit on a 4GB hard
+ drive. The attacker need only sort them, and then check for matches.
+ Since a 4GB hard drive can be had for under $1000.00, this is well
+ within the means of most system crackers.
+
+ Also, if a cracker obtains your /etc/passwd file first, they only need
+ to encode the dictionary with the salt values actually contained in
+ your /etc/passwd file. This method is usable by your average teenager
+ with a couple of hundred spare Megabytes and a 486 class computer.
+
+ Even without lots of drive space, utilities like crack(1) can usually
+ break at least a couple of passwords on a system with enough users
+ (assuming the users of the system are allowed to pick their own
+ passwords).
+
+ The /etc/passwd file also contains information like user ID's and
+ group ID's that are used by many system programs. Therefore, the
+ /etc/passwd file must remain world readable. If you were to change
+ the /etc/passwd file so that nobody can read it, the first thing that
+ you would notice is that the ls -l command now displays user ID's
+ instead of names!
+
+ The Shadow Suite solves the problem by relocating the passwords to
+ another file (usually /etc/shadow). The /etc/shadow file is set so
+ that it cannot be read by just anyone. Only root will be able to read
+ and write to the /etc/shadow file. Some programs (like xlock) don't
+ need to be able to change passwords, they only need to be able to
+ verify them. These programs can either be run suid root or you can
+ set up a group shadow that is allowed read only access to the
+ /etc/shadow file. Then the program can be run sgid shadow.
+
+ By moving the passwords to the /etc/shadow file, we are effectively
+ keeping the attacker from having access to the encoded passwords with
+ which to perform a dictionary attack.
+
+ Additionally, the Shadow Suite adds lots of other nice features:
+
+ · A configuration file to set login defaults (/etc/login.defs)
+
+ · Utilities for adding, modifying, and deleting user accounts and
+ groups
+
+ · Password aging and expiration
+
+ · Account expiration and locking
+
+ · Shadowed group passwords (optional)
+
+ · Double length passwords (16 character passwords) NOT RECOMMENDED
+
+ · Better control over user's password selection
+
+ · Dial-up passwords
+
+ · Secondary authentication programs NOT RECOMMENDED
+
+ Installing the Shadow Suite contributes toward a more secure system,
+ but there are many other things that can also be done to improve the
+ security of a Linux system, and there will eventually be a series of
+ Linux Security HOWTO's that will discuss other security measures and
+ related issues.
+
+ For current information on other Linux security issues, including
+ warnings on known vulnerabilities see the Linux Security home page.
+ <http://bach.cis.temple.edu/linux/linux-security/>
+
+ 2.1. Why you might NOT want to shadow your passwd file.
+
+ There are a few circumstances and configurations in which installing
+ the Shadow Suite would NOT be a good idea:
+
+ · The machine does not contain user accounts.
+
+ · Your machine is running on a LAN and is using NIS (Network
+ Information Services) to get or supply user names and passwords to
+ other machines on the network. (This can actually be done, but is
+ beyond the scope of this document, and really won't increase
+ security much anyway)
+
+ · Your machine is being used by terminal servers to verify users via
+ NFS (Network File System), NIS, or some other method.
+
+ · Your machine runs other software that validates users, and there is
+ no shadow version available, and you don't have the source code.
+
+ 2.2. Format of the /etc/passwd file
+
+ A non-shadowed /etc/passwd file has the following format:
+
+ username:passwd:UID:GID:full_name:directory:shell
+
+ Where:
+
+ username
+ The user (login) name
+
+ passwd
+ The encoded password
+
+ UID
+ Numerical user ID
+
+ GID
+ Numerical default group ID
+
+ full_name
+ The user's full name - Actually this field is called the GECOS
+ (General Electric Comprehensive Operating System) field and can
+ store information other than just the full name. The Shadow
+ commands and manual pages refer to this field as the comment
+ field.
+
+ directory
+ User's home directory (Full pathname)
+
+ shell
+ User's login shell (Full Pathname)
+
+ For example:
+
+ username:Npge08pfz4wuk:503:100:Full Name:/home/username:/bin/sh
+
+ Where Np is the salt and ge08pfz4wuk is the encoded password. The
+ encoded salt/password could just as easily have been kbeMVnZM0oL7I and
+ the two are exactly the same password. There are 4096 possible encod­
+ ings for the same password. (The example password in this case is
+ 'password', a really bad password).
+
+ Once the shadow suite is installed, the /etc/passwd file would instead
+ contain:
+
+ username:x:503:100:Full Name:/home/username:/bin/sh
+
+ The x in the second field in this case is now just a place holder.
+ The format of the /etc/passwd file really didn't change, it just no
+ longer contains the encoded password. This means that any program
+ that reads the /etc/passwd file but does not actually need to verify
+ passwords will still operate correctly.
+
+ The passwords are now relocated to the shadow file (usually
+ /etc/shadow file).
+
+ 2.3. Format of the shadow file
+
+ The /etc/shadow file contains the following information:
+
+ username:passwd:last:may:must:warn:expire:disable:reserved
+
+ Where:
+
+ username
+ The User Name
+
+ passwd
+ The Encoded password
+ last
+ Days since Jan 1, 1970 that password was last changed
+
+ may
+ Days before password may be changed
+
+ must
+ Days after which password must be changed
+
+ warn
+ Days before password is to expire that user is warned
+
+ expire
+ Days after password expires that account is disabled
+
+ disable
+ Days since Jan 1, 1970 that account is disabled
+
+ reserved
+ A reserved field
+
+ The previous example might then be:
+
+ username:Npge08pfz4wuk:9479:0:10000::::
+
+ 2.4. Review of crypt(3).
+
+ From the crypt(3) manual page:
+
+ "crypt is the password encryption function. It is based on the Data
+ Encryption Standard algorithm with variations intended (among other
+ things) to discourage use of hardware implementations of a key search.
+
+ The key is a user's typed password. The encoded string is all NULLs
+
+ The salt is a two-character string chosen from the set a-zA-Z0-9./.
+ This string is used to perturb the algorithm in one of 4096 different
+ ways.
+
+ By taking the lowest 7 bits of each character of the key, a 56-bit key
+ is obtained. This 56-bit key is used to encrypt repeatedly a constant
+ string (usually a string consisting of all zeros). The returned value
+ points to the encrypted password, a series of 13 printable ASCII
+ characters (the first two characters represent the salt itself). The
+ return value points to static data whose content is overwritten by
+ each call.
+
+ Warning: The key space consists of 2**56 equal 7.2e16 possible values.
+ Exhaustive searches of this key space are possible using massively
+ parallel computers. Software, such as crack(1), is available which
+ will search the portion of this key space that is generally used by
+ humans for passwords. Hence, password selection should, at minimum,
+ avoid common words and names. The use of a passwd(1) program that
+ checks for crackable passwords during the selection process is
+ recommended.
+
+ The DES algorithm itself has a few quirks which make the use of the
+ crypt(3) interface a very poor choice for anything other than password
+ authentication. If you are planning on using the crypt(3) interface
+ for a cryptography project, don't do it: get a good book on encryption
+ and one of the widely available DES libraries."
+
+ Most Shadow Suites contain code for doubling the length of the
+ password to 16 characters. Experts in des recommend against this, as
+ the encoding is simply applied first to the left half and then to the
+ right half of the longer password. Because of the way crypt works,
+ this may make for a less secure encoded password then if double length
+ passwords were not used in the first place. Additionally, it is less
+ likely that a user will be able to remember a 16 character password.
+
+ There is development work under way that would allow the
+ authentication algorithm to be replaced with something more secure and
+ with support for longer passwords (specifically the MD5 algorithm) and
+ retain compatibility with the crypt method.
+
+ If you are looking for a good book on encryption, I recommend:
+
+ "Applied Cryptography: Protocols, Algorithms, and Source Code in C"
+ by Bruce Schneier <schneier@chinet.com>
+ ISBN: 0-471-59756-2
+
+ 3. Getting the Shadow Suite.
+
+ 3.1. History of the Shadow Suite for Linux
+
+ DO NOT USE THE PACKAGES IN THIS SECTION, THEY HAVE SECURITY PROBLEMS
+
+ The original Shadow Suite was written by Julianne F. Haugh
+
+ There are several versions that have been used on Linux systems:
+
+ · shadow-3.3.1 is the original.
+
+ · shadow-3.3.1-2 is Linux specific patch made by Florian La Roche
+ <flla@stud.uni-sb.de> and contains some further enhancements.
+
+ · shadow-mk was specifically packaged for Linux.
+
+ The shadow-mk package contains the shadow-3.3.1 package distributed by
+ Julianne F. Haugh with the shadow-3.3.1-2 patch installed, a few fixes
+ made by Mohan Kokal <magnus@texas.net> that make installation a lot
+ easier, a patch by Joseph R.M. Zbiciak for login1.c (login.secure)
+ that eliminates the -f, -h security holes in /bin/login, and some
+ other miscellaneous patches.
+
+ The shadow.mk package was the previously recommended package, but
+ should be replaced due to a security problem with the login program.
+
+ There are security problems with Shadow versions 3.3.1, 3.3.1-2, and
+ shadow-mk involving the login program. This login bug involves not
+ checking the length of a login name. This causes the buffer to
+ overflow causing crashes or worse. It has been rumored that this
+ buffer overflow can allow someone with an account on the system to use
+ this bug and the shared libraries to gain root access. I won't
+ discuss exactly how this is possible because there are a lot of Linux
+ systems that are affected, but systems with these Shadow Suites
+ installed, and most pre-ELF distributions without the Shadow Suite are
+ vulnerable!
+
+ For more information on this and other Linux security issues, see the
+ Linux Security home page (Shared Libraries and login Program
+ Vulnerability) <http://bach.cis.temple.edu/linux/linux-security/Linux-
+ Security-FAQ/Linux-telnetd.html>
+
+ 3.2. Where to get the Shadow Suite.
+
+ The only recommended Shadow Suite is still in BETA testing, however
+ the latest versions are safe in a production environment and don't
+ contain a vulnerable login program.
+
+ The package uses the following naming convention:
+
+ shadow-YYMMDD.tar.gz
+
+ where YYMMDD is the issue date of the Suite.
+
+ This version will eventually be Version 3.3.3 when it is released from
+ Beta testing, and is maintained by Marek Michalkiewicz
+ <marekm@i17linuxb.ists.pwr.wroc.pl>. It's available as: shadow-
+ current.tar.gz
+ <ftp://i17linuxb.ists.pwr.wroc.pl/pub/linux/shadow/shadow-
+ current.tar.gz>.
+
+ The following mirror sites have also been established:
+
+ · ftp://ftp.icm.edu.pl/pub/Linux/shadow/shadow-current.tar.gz
+
+ · ftp://iguana.hut.fi/pub/linux/shadow/shadow-current.tar.gz
+
+ · ftp://ftp.cin.net/usr/ggallag/shadow/shadow-current.tar.gz
+
+ · ftp://ftp.netural.com/pub/linux/shadow/shadow-current.tar.gz
+
+ You should use the currently available version.
+
+ You should NOT use a version older than shadow-960129 as they also
+ have the login security problem discussed above.
+
+ When this document refers to the Shadow Suite I am referring to the
+ this package. It is assumed that this is the package that you are
+ using.
+
+ For reference, I used shadow-960129 to make these installation
+ instructions.
+
+ If you were previously using shadow-mk, you should upgrade to this
+ version and rebuild everything that you originally compiled.
+
+ 3.3. What is included with the Shadow Suite.
+
+ The Shadow Suite contains replacement programs for:
+
+ su, login, passwd, newgrp, chfn, chsh, and id
+
+ The package also contains the new programs:
+
+ chage, newusers, dpasswd, gpasswd, useradd, userdel, usermod,
+ groupadd, groupdel, groupmod, groups, pwck, grpck, lastlog, pwconv,
+ and pwunconv
+
+ Additionally, the library: libshadow.a is included for writing and/or
+ compiling programs that need to access user passwords.
+
+ Also, manual pages for the programs are also included.
+
+ There is also a configuration file for the login program which will be
+ installed as /etc/login.defs.
+
+ 4. Compiling the programs.
+
+ 4.1. Unpacking the archive.
+
+ The first step after retrieving the package is unpacking it. The
+ package is in the tar (tape archive) format and compressed using gzip,
+ so first move it to /usr/src, then type:
+
+ tar -xzvf shadow-current.tar.gz
+
+ This will unpack it into the directory: /usr/src/shadow-YYMMDD
+
+ 4.2. Configuring with the config.h file
+
+ The first thing that you need to do is to copy over the Makefile and
+ the config.h file:
+
+ cd /usr/src/shadow-YYMMDD
+ cp Makefile.linux Makefile
+ cp config.h.linux config.h
+
+ You should then take a look at the config.h file. This file contains
+ definitions for some of the configuration options. If you are using
+ the recommended package, I recommend that you disable group shadow
+ support for your first time around.
+
+ By default shadowed group passwords are enabled. To disable these
+ edit the config.h file, and change the #define SHADOWGRP to #undef
+ SHADOWGRP. I recommend that you disable them to start with, and then
+ if you really want group passwords and group administrators that you
+ enable it later and recompile. If you leave it enabled, you must
+ create the file /etc/gshadow.
+
+ Enabling the long passwords option is NOT recommended as discussed
+ above.
+
+ Do NOT change the setting: #undef AUTOSHADOW
+
+ The AUTOSHADOW option was originally designed so that programs that
+ were shadow ignorant would still function. This sounds good in
+ theory, but does not work correctly. If you enable this option, and
+ the program runs as root, it may call getpwnam() as root, and later
+ write the modified entry back to the /etc/passwd file (with the no-
+ longer-shadowed password). Such programs include chfn and chsh. (You
+ can't get around this by swapping real and effective uid before
+ calling getpwnam() because root may use chfn and chsh too.)
+
+ The same warning is also valid if you are building libc, it has a
+ SHADOW_COMPAT option which does the same thing. It should NOT be
+ used! If you start getting encoded passwords back in your /etc/passwd
+ file, this is the problem.
+
+ If you are using a libc version prior to 4.6.27, you will need to make
+ a couple more changes to config.h and the Makefile. To config.h edit
+ and change:
+
+ #define HAVE_BASENAME
+
+ to:
+
+ #undef HAVE_BASENAME
+
+ And then in the Makefile, change:
+
+ SOBJS = smain.o env.o entry.o susetup.o shell.o \
+ sub.o mail.o motd.o sulog.o age.o tz.o hushed.o
+
+ SSRCS = smain.c env.c entry.c setup.c shell.c \
+ pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \
+ tz.c hushed.c
+
+ SOBJS = smain.o env.o entry.o susetup.o shell.o \
+ sub.o mail.o motd.o sulog.o age.o tz.o hushed.o basename.o
+
+ SSRCS = smain.c env.c entry.c setup.c shell.c \
+ pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \
+ tz.c hushed.c basename.c
+
+ These changes add the code contained in basename.c which is contained
+ in libc 4.6.27 and later.
+
+ 4.3. Making backup copies of your original programs.
+
+ It would also be a good idea to track down and make backup copies of
+ the programs that the shadow suite will replace. On a Slackware 3.0
+ system these are:
+
+ · /bin/su
+
+ · /bin/login
+
+ · /usr/bin/passwd
+
+ · /usr/bin/newgrp
+
+ · /usr/bin/chfn
+
+ · /usr/bin/chsh
+
+ · /usr/bin/id
+
+ The BETA package has a save target in the Makefile, but it's commented
+ out because different distributions place the programs in different
+ places.
+
+ You should also make a backup copy of your /etc/passwd file, but be
+ careful to name it something else if you place it in the same
+ directory so you don't overwrite the passwd command.
+
+ 4.4. Running make
+
+ You need to be logged as root to do most of the installation.
+
+ Run make to compile the executables in the package:
+
+ make all
+
+ You may see the warning: rcsid defined but not used. This is fine, it
+ just happens because the author is using a version control package.
+
+ 5. Installing
+
+ 5.1. Have a boot disk handy in case you break anything.
+
+ If something goes terribly wrong, it would be handy to have a boot
+ disk. If you have a boot/root combination from your installation,
+ that will work, otherwise see the Bootdisk-HOWTO
+ <http://sunsite.unc.edu/mdw/HOWTO/Bootdisk-HOWTO.html>, which
+ describes how to make a bootable disk.
+
+ 5.2. Removing duplicate man pages
+
+ You should also move the manual pages that are about to be replaced.
+ Even if you are brave enough install the Shadow Suite without making
+ backups, you will still want to remove the old manual pages. The new
+ manual pages won't normally overwrite the old ones because the old
+ ones are probably compressed.
+
+ You can use a combination of: man -aW command and locate command to
+ locate the manual pages that need to be (re)moved. It's generally
+ easier to figure out which are the older pages before you run make
+ install.
+
+ If you are using the Slackware 3.0 distribution, then the manual pages
+ you want to remove are:
+
+ · /usr/man/man1/chfn.1.gz
+
+ · /usr/man/man1/chsh.1.gz
+
+ · /usr/man/man1/id.1.gz
+
+ · /usr/man/man1/login.1.gz
+
+ · /usr/man/man1/passwd.1.gz
+
+ · /usr/man/man1/su.1.gz
+
+ · /usr/man/man5/passwd.5.gz
+
+ There may also be man pages of the same name in the /var/man/cat[1-9]
+ subdirectories that should also be deleted.
+
+ 5.3. Running make install
+
+ You are now ready to type: (do this as root)
+
+ make install
+
+ This will install the new and replacement programs and fix-up the file
+ permissions. It will also install the man pages.
+
+ This also takes care of installing the Shadow Suite include files in
+ the correct places in /usr/include/shadow.
+
+ Using the BETA package you must manually copy the file login.defs to
+ the /etc subdirectory and make sure that only root can make changes to
+ it.
+
+ cp login.defs /etc
+ chmod 700 /etc/login.defs
+
+ This file is the configuration file for the login program. You should
+ review and make changes to this file for your particular system. This
+ is where you decide which tty's root can login from, and set other
+ security policy settings (like password expiration defaults).
+
+ 5.4. Running pwconv
+
+ The next step is to run pwconv. This must also be done as root, and
+ is best done from the /etc subdirectory:
+
+ cd /etc
+ /usr/sbin/pwconv
+
+ pwconv takes your /etc/passwd file and strips out the fields to create
+ two files: /etc/npasswd and /etc/nshadow.
+
+ A pwunconv program is also provided if you need to make a normal
+ /etc/passwd file out of an /etc/passwd and /etc/shadow combination.
+
+ 5.5. Renaming npasswd and nshadow
+
+ Now that you have run pwconv you have created the files /etc/npasswd
+ and /etc/nshadow. These need to be copied over to /etc/passwd and
+ /etc/shadow. We also want to make a backup copy of the original
+ /etc/passwd file, and make sure only root can read it. We'll put the
+ backup in root's home directory:
+
+ cd /etc
+ cp passwd ~passwd
+ chmod 600 ~passwd
+ mv npasswd passwd
+ mv nshadow shadow
+
+ You should also ensure that the file ownerships and permissions are
+ correct. If you are going to be using X-Windows, the xlock and xdm
+ programs need to be able to read the shadow file (but not write it).
+
+ There are two ways that this can be done. You can set xlock to suid
+ root (xdm is usually run as root anyway). Or you can make the shadow
+ file owned by root with a group of shadow, but before you do this,
+ make sure that you have a shadow group (look in /etc/group). None of
+ the users on the system should actually be in the shadow group.
+
+ chown root.root passwd
+ chown root.shadow shadow
+ chmod 0644 passwd
+ chmod 0640 shadow
+
+ Your system now has the password file shadowed. You should now pop
+ over to another virtual terminal and verify that you can login.
+
+ Really, do this now!
+
+ If you can't, then something is wrong! To get back to a non-shadowed
+ state, do the following the following:
+
+ cd /etc
+ cp ~passwd passwd
+ chmod 644 passwd
+
+ You would then restore the files that you saved earlier to their
+ proper locations.
+
+ 6. Other programs you may need to upgrade or patch
+
+ Even though the shadow suite contains replacement programs for most
+ programs that need to access passwords, there are a few additional
+ programs on most systems that require access to passwords.
+
+ If you are running a Debian Distribution (or even if you are not), you
+ can obtain Debian sources for the programs that need to be rebuild
+ from: ftp://ftp.debian.org/debian/stable/source/
+
+ The remainder of this section discusses how to upgrade adduser,
+ wu_ftpd, ftpd, pop3d, xlock, xdm and sudo so that they support the
+ shadow suite.
+
+ See the section ``Adding Shadow Support to a C program'' for a
+ discussion on how to put shadow support into any other program that
+ needs it (although the program must then be run SUID root or SGID
+ shadow to be able to actually access the shadow file).
+
+ 6.1. Slackware adduser program
+
+ Slackware distributions (and possibly some others) contain a
+ interactive program for adding users called /sbin/adduser. A shadow
+ version of this program can be obtained from
+ ftp://sunsite.unc.edu/pub/Linux/
+ system/Admin/accounts/adduser.shadow-1.4.tar.gz.
+
+ I would encourage you to use the programs that are supplied with the
+ Shadow Suite (useradd, usermod, and userdel) instead of the slackware
+ adduser program. They take a little time to learn how to use, but
+ it's well worth the effort because you have much more control and they
+ perform proper file locking on the /etc/passwd and /etc/shadow file
+ (adduser doesn't).
+
+ See the section on ``Putting the Shadow Suite to use'' for more
+ information.
+
+ But if you gotta have it, here is what you do:
+
+ tar -xzvf adduser.shadow-1.4.tar.gz
+ cd adduser
+ make clean
+ make adduser
+ chmod 700 adduser
+ cp adduser /sbin
+
+ 6.2. The wu_ftpd Server
+
+ Most Linux systems some with the wu_ftpd server. If your distribution
+ does not come with shadow installed, then your wu_ftpd will not be
+ compiled for shadow. wu_ftpd is launched from inetd/tcpd as a root
+ process. If you are running an old wu_ftpd daemon, you will want to
+ upgrade it anyway because older ones had a bug that would allow the
+ root account to be compromised (For more info see the Linux security
+ home page <http://bach.cis.temple.edu/linux/linux-security/Linux-
+ Security-FAQ/Linux-wu.ftpd-2.4-Update.html>).
+
+ Fortunately, you only need to get the source code and recompile it
+ with shadow enabled.
+
+ If you are not running an ELF system, The wu_ftp server can be found
+ on Sunsite as wu-ftp-2.4-fixed.tar.gz
+ <ftp://sunsite.unc.edu/pub/Linux/system/Network/file-transfer/wu-
+ ftpd-2.4-fixed.tar.gz>
+
+ Once you retrieve the server, put it in /usr/src, then type:
+
+ cd /usr/src
+ tar -xzvf wu-ftpd-2.4-fixed.tar.gz
+ cd wu-ftpd-2.4-fixed
+ cp ./src/config/config.lnx.shadow ./src/config/config.lnx
+
+ Then edit ./src/makefiles/Makefile.lnx, and change the line:
+
+ LIBES = -lbsd -support
+
+ to:
+
+ LIBES = -lbsd -support -lshadow
+
+ Now you are ready to run the build script and install:
+
+ cd /usr/src/wu-ftpd-2.4-fixed
+ /usr/src/wu-ftp-2.4.fixed/build lnx
+ cp /usr/sbin/wu.ftpd /usr/sbin/wu.ftpd.old
+ cp ./bin/ftpd /usr/sbin/wu.ftpd
+
+ This uses the Linux shadow configuration file, compiles and installs
+ the server.
+
+ On my Slackware 2.3 system I also had to do the following before
+ running build:
+
+ cd /usr/include/netinet
+ ln -s in_systm.h in_system.h
+ cd -
+
+ Problems have been reported compiling this package under ELF systems,
+ but the Beta version of the next release works fine. It can be found
+ as wu-ftp-2.4.2-beta-10.tar.gz
+ <ftp://tscnet.com/pub/linux/network/ftp/wu-ftpd-2.4.2-beta-10.tar.gz>
+
+ Once you retrieve the server, put it in /usr/src, then type:
+
+ cd /usr/src
+ tar -xzvf wu-ftpd-2.4.2-beta-9.tar.gz
+ cd wu-ftpd-beta-9
+ cd ./src/config
+
+ Then edit config.lnx, and change:
+
+ #undef SHADOW.PASSWORD
+
+ to:
+
+ #define SHADOW.PASSWORD
+
+ Then,
+
+ cd ../Makefiles
+
+ and edit the file Makefile.lnx and change:
+
+ LIBES = -lsupport -lbsd # -lshadow
+
+ to:
+
+ LIBES = -lsupport -lbsd -lshadow
+
+ Then build and install:
+
+ cd ..
+ build lnx
+ cp /usr/sbin/wu.ftpd /usr/sbin/wu.ftpd.old
+ cp ./bin/ftpd /usr/sbin/wu.ftpd
+
+ Note that you should check your /etc/inetd.conf file to make sure that
+ this is where your wu.ftpd server really lives. It has been reported
+ that some distributions place the server daemons in different places,
+ and then wu.ftpd in particular may be named something else.
+
+ 6.3. Standard ftpd
+
+ If you are running the standard ftpd server, I would recommend that
+ you upgrade to the wu_ftpd server. Aside from the known bug discussed
+ above, it's generally thought to be more secure.
+
+ If you insist on the standard one, or you need NIS support, Sunsite
+ has ftpd-shadow-nis.tgz
+ <ftp://sunsite.unc.edu/pub/Linux/system/Network/file-transfer/ftpd-
+ shadow-nis.tgz>
+
+ 6.4. pop3d (Post Office Protocol 3)
+
+ If you need to support the third Post Office Protocol (POP3), you will
+ need to recompile a pop3d program. pop3d is normally run by
+ inetd/tcpd as root.
+
+ There are two versions available from Sunsite:
+ pop3d-1.00.4.linux.shadow.tar.gz
+ <ftp://sunsite.unc.edu/pub/Linux/system/Mail/pop/pop3d-1.00.4.linux.shadow.tar.gz>
+ and pop3d+shadow+elf.tar.gz
+ <ftp://sunsite.unc.edu/pub/Linux/system/Mail/pop/pop3d+shadow+elf.tar.gz>
+
+ Both of these are fairly straight forward to install.
+
+ 6.5. xlock
+
+ If you install the shadow suite, and then run X Windows System and
+ lock the screen without upgrading your xlock, you will have to use
+ CNTL-ALT-Fx to switch to another tty, login, and kill the xlock
+ process (or use CNTL-ALT-BS to kill the X server). Fortunately it's
+ fairly easy to upgrade your xlock program.
+
+ If you are running XFree86 Versions 3.x.x, you are probably using
+ xlockmore (which is a great screen-saver in addition to a lock). This
+ package supports shadow with a recompile. If you have an older xlock,
+ I recommend that you upgrade to this one.
+
+ xlockmore-3.5.tgz is available at:
+ <ftp://sunsite.unc.edu/pub/Linux/X11/xutils/screensavers/xlockmore-3.7.tgz>
+
+ Basically, this is what you need to do:
+
+ Get the xlockmore-3.7.tgz file and put it in /usr/src unpack it:
+
+ tar -xzvf xlockmore-3.7.tgz
+
+ Edit the file: /usr/X11R6/lib/X11/config/linux.cf, and change the
+ line:
+
+ #define HasShadowPasswd NO
+
+ to
+
+ #define HasShadowPasswd YES
+
+ Then build the executables:
+
+ cd /usr/src/xlockmore
+ xmkmf
+ make depend
+ make
+
+ Then move everything into place and update file ownerships and
+ permissions:
+
+ cp xlock /usr/X11R6/bin/
+ cp XLock /var/X11R6/lib/app-defaults/
+ chown root.shadow /usr/X11R6/bin/xlock
+ chmod 2755 /usr/X11R6/bin/xlock
+ chown root.shadow /etc/shadow
+ chmod 640 /etc/shadow
+
+ Your xlock will now work correctly.
+
+ 6.6. xdm
+
+ xdm is a program that presents a login screen for X-Windows. Some
+ systems start xdm when the system is told to goto a specified run
+ level (see /etc/inittab.
+
+ With the Shadow Suite install, xdm will need to be updated.
+ Fortunately it's fairly easy to upgrade your xdm program.
+
+ xdm.tar.gz is available at:
+ <ftp://sunsite.unc.edu/pub/Linux/X11/xutils/xdm.tar.gz>
+
+ Get the xdm.tar.gz file and put it in /usr/src, then to unpack it:
+
+ tar -xzvf xdm.tar.gz
+
+ Edit the file: /usr/X11R6/lib/X11/config/linux.cf, and change the
+ line:
+
+ #define HasShadowPasswd NO
+
+ to
+
+ #define HasShadowPasswd YES
+
+ Then build the executables:
+
+ cd /usr/src/xdm
+ xmkmf
+ make depend
+ make
+
+ Then move everything into place:
+
+ cp xdm /usr/X11R6/bin/
+
+ xdm is run as root so you don't need to change it file permissions.
+
+ 6.7. sudo
+
+ The program sudo allows a system administrator to let users run
+ programs that would normally require root access. This is handy
+ because it lets the administrator limit access to the root account
+ itself while still allowing users to do things like mounting drives.
+
+ sudo needs to read passwords because it verifies the users password
+ when it's invoked. sudo already runs SUID root, so accessing the
+ /etc/shadow file is not a problem.
+
+ sudo for the shadow suite, is available as at:
+ <ftp://sunsite.unc.edu/pub/Linux/system/Admin/sudo-1.2-shadow.tgz>
+
+ Warning: When you install sudo your /etc/sudoers file will be replaced
+ with a default one, so you need to make a backup of it if you have
+ added anything to the default one. (you could also edit the Makefile
+ and remove the line that copies the default file to /etc).
+
+ The package is already setup for shadow, so all that's required is to
+ recompile the package (put it in /usr/src):
+
+ cd /usr/src
+ tar -xzvf sudo-1.2-shadow.tgz
+ cd sudo-1.2-shadow
+ make all
+ make install
+
+ 6.8. imapd (E-Mail pine package)
+
+ imapd is an e-mail server similar to pop3d. imapd comes with the Pine
+ E-mail package. The documentation that comes with the package states
+ that the default for Linux systems is to include support for shadow.
+ However, I have found that this is not true. Furthermore, the build
+ script / Makefile combination on this package is makes it very
+ difficult to add the libshadow.a library at compile time, so I was
+ unable to add shadow support for imapd.
+
+ If anyone has this figured out, please E-mail me, and I'll include the
+ solution here.
+
+ 6.9. pppd (Point-to-Point Protocol Server)
+
+ The pppd server can be setup to use several types of authentication:
+ Password Authentication Protocol (PAP) and Cryptographic Handshake
+ Authentication Protocol (CHAP). The pppd server usually reads the
+ password strings that it uses from /etc/ppp/chap-secrets and/or
+ /etc/ppp/pap-secrets. If you are using this default behavior of pppd,
+ it is not necessary to reinstall pppd.
+
+ pppd also allows you to use the login parameter (either on the command
+ line, or in the configuration or options file). If the login option
+ is given, then pppd will use the /etc/passwd file for the username and
+ passwords for the PAP. This, of course, will no longer work now that
+ our password file is shadowed. For pppd-1.2.1d this requires adding
+ code for shadow support.
+
+ The example given in the next section is adding shadow support to
+ pppd-1.2.1d (an older version of pppd).
+
+ pppd-2.2.0 already contains shadow support.
+
+ 7. Putting the Shadow Suite to use.
+
+ This section discusses some of the things that you will want to know
+ now that you have the Shadow Suite installed on your system. More
+ information is contained in the manual pages for each command.
+
+ 7.1. Adding, Modifying, and deleting users
+
+ The Shadow Suite added the following command line oriented commands
+ for adding, modifying, and deleting users. You may also have
+ installed the adduser program.
+
+ 7.1.1. useradd
+
+ The useradd command can be used to add users to the system. You also
+ invoke this command to change the default settings.
+
+ The first thing that you should do is to examine the default settings
+ and make changes specific to your system:
+
+ useradd -D
+
+ ______________________________________________________________________
+ GROUP=1
+ HOME=/home
+ INACTIVE=0
+ EXPIRE=0
+ SHELL=
+ SKEL=/etc/skel
+ ______________________________________________________________________
+
+ The defaults are probably not what you want, so if you started adding
+ users now you would have to specify all the information for each user.
+ However, we can and should change the default values.
+
+ On my system:
+
+ · I want the default group to be 100
+
+ · I want passwords to expire every 60 days
+
+ · I don't want to lock an account because the password is expired
+
+ · I want to default shell to be /bin/bash
+
+ To make these changes I would use:
+
+ useradd -D -g100 -e60 -f0 -s/bin/bash
+
+ Now running useradd -D will give:
+
+ ______________________________________________________________________
+ GROUP=100
+ HOME=/home
+ INACTIVE=0
+ EXPIRE=60
+ SHELL=/bin/bash
+ SKEL=/etc/skel
+ ______________________________________________________________________
+
+ Just in case you wanted to know, these defaults are stored in the file
+ /etc/default/useradd.
+
+ Now you can use useradd to add users to the system. For example, to
+ add the user fred, using the defaults, you would use the following:
+
+ useradd -m -c "Fred Flintstone" fred
+
+ This will create the following entry in the /etc/passwd file:
+
+ fred:*:505:100:Fred Flintstone:/home/fred:/bin/bash
+
+ And the following entry in the /etc/shadow file:
+
+ fred:!:0:0:60:0:0:0:0
+
+ fred's home directory will be created and the contents of /etc/skel
+ will be copied there because of the -m switch.
+
+ Also, since we did not specify a UID, the next available one was used.
+
+ fred's account is created, but fred still won't be able to login until
+ we unlock the account. We do this by changing the password.
+
+ passwd fred
+
+ ______________________________________________________________________
+ Changing password for fred
+ Enter the new password (minimum of 5 characters)
+ Please use a combination of upper and lower case letters and numbers.
+ New Password: *******
+ Re-enter new password: *******
+ ______________________________________________________________________
+
+ Now the /etc/shadow will contain:
+
+ fred:J0C.WDR1amIt6:9559:0:60:0:0:0:0
+
+ And fred will now be able to login and use the system. The nice thing
+ about useradd and the other programs that come with the Shadow Suite
+ is that they make changes to the /etc/passwd and /etc/shadow files
+ atomically. So if you are adding a user, and another user is changing
+ their password at the same time, both operations will be performed
+ correctly.
+
+ You should use the supplied commands rather than directly editing
+ /etc/passwd and /etc/shadow. If you were editing the /etc/shadow
+ file, and a user were to change his password while you are editing,
+ and then you were to save the file you were editing, the user's
+ password change would be lost.
+
+ Here is a small interactive script that adds users using useradd and
+ passwd:
+
+ ______________________________________________________________________
+ #!/bin/bash
+ #
+ # /sbin/newuser - A script to add users to the system using the Shadow
+ # Suite's useradd and passwd commands.
+ #
+ # Written my Mike Jackson <mhjack@tscnet.com> as an example for the Linux
+ # Shadow Password Howto. Permission to use and modify is expressly granted.
+ #
+ # This could be modified to show the defaults and allow modification similar
+ # to the Slackware Adduser program. It could also be modified to disallow
+ # stupid entries. (i.e. better error checking).
+ #
+ ##
+ # Defaults for the useradd command
+ ##
+ GROUP=100 # Default Group
+ HOME=/home # Home directory location (/home/username)
+ SKEL=/etc/skel # Skeleton Directory
+ INACTIVE=0 # Days after password expires to disable account (0=never)
+ EXPIRE=60 # Days that a passwords lasts
+ SHELL=/bin/bash # Default Shell (full path)
+ ##
+ # Defaults for the passwd command
+ ##
+ PASSMIN=0 # Days between password changes
+ PASSWARN=14 # Days before password expires that a warning is given
+ ##
+ # Ensure that root is running the script.
+ ##
+ WHOAMI=`/usr/bin/whoami`
+ if [ $WHOAMI != "root" ]; then
+ echo "You must be root to add news users!"
+ exit 1
+ fi
+ ##
+ # Ask for username and fullname.
+ ##
+ echo ""
+ echo -n "Username: "
+ read USERNAME
+ echo -n "Full name: "
+ read FULLNAME
+ #
+ echo "Adding user: $USERNAME."
+ #
+ # Note that the "" around $FULLNAME is required because this field is
+ # almost always going to contain at least on space, and without the "'s
+ # the useradd command would think that you we moving on to the next
+ # parameter when it reached the SPACE character.
+ #
+ /usr/sbin/useradd -c"$FULLNAME" -d$HOME/$USERNAME -e$EXPIRE \
+ -f$INACTIVE -g$GROUP -m -k$SKEL -s$SHELL $USERNAME
+ ##
+ # Set password defaults
+ ##
+ /bin/passwd -n $PASSMIN -w $PASSWARN $USERNAME >/dev/null 2>&1
+ ##
+ # Let the passwd command actually ask for password (twice)
+ ##
+ /bin/passwd $USERNAME
+ ##
+ # Show what was done.
+ ##
+ echo ""
+ echo "Entry from /etc/passwd:"
+ echo -n " "
+ grep "$USERNAME:" /etc/passwd
+ echo "Entry from /etc/shadow:"
+ echo -n " "
+ grep "$USERNAME:" /etc/shadow
+ echo "Summary output of the passwd command:"
+ echo -n " "
+ passwd -S $USERNAME
+ echo ""
+ ______________________________________________________________________
+
+ Using a script to add new users is really much more preferable than
+ editing the /etc/passwd or /etc/shadow files directly or using a
+ program like the Slackware adduser program. Feel free to use and
+ modify this script for your particular system.
+
+ For more information on the useradd see the online manual page.
+
+ 7.1.2. usermod
+
+ The usermod program is used to modify the information on a user. The
+ switches are similar to the useradd program.
+
+ Let's say that you want to change fred's shell, you would do the
+ following:
+
+ usermod -s /bin/tcsh fred
+
+ Now fred's /etc/passwd file entry would be change to this:
+
+ fred:*:505:100:Fred Flintstone:/home/fred:/bin/tcsh
+
+ Let's make fred's account expire on 09/15/97:
+
+ usermod -e 09/15/97 fred
+
+ Now fred's entry in /etc/shadow becomes:
+
+ fred:J0C.WDR1amIt6:9559:0:60:0:0:10119:0
+
+ For more information on the usermod command see the online manual
+ page.
+
+ 7.1.3. userdel
+
+ userdel does just what you would expect, it deletes the user's
+ account. You simply use:
+
+ userdel -r username
+
+ The -r causes all files in the user's home directory to be removed
+ along with the home directory itself. Files located in other file
+ system will have to be searched for and deleted manually.
+
+ If you want to simply lock the account rather than delete it, use the
+ passwd command instead.
+
+ 7.2. The passwd command and passwd aging.
+
+ The passwd command has the obvious use of changing passwords.
+ Additionally, it is used by the root user to:
+
+ · Lock and unlock accounts (-l and -u)
+
+ · Set the maximum number of days that a password remains valid (-x)
+
+ · Set the minimum days between password changes (-n)
+
+ · Sets the number of days of warning that a password is about to
+ expire (-w)
+
+ · Sets the number of days after the password expires before the
+ account is locked (-i)
+
+ · Allow viewing of account information in a clearer format (-S)
+
+ For example, let look again at fred
+
+ passwd -S fred
+ fred P 03/04/96 0 60 0 0
+
+ This means that fred's password is valid, it was last changed on
+ 03/04/96, it can be changed at any time, it expires after 60 days,
+ fred will not be warned, and and the account won't be disabled when
+ the password expires.
+
+ This simply means that if fred logs in after the password expires, he
+ will be prompted for a new password at login.
+
+ If we decide that we want to warn fred 14 days before his password
+ expires and make his account inactive 14 days after he lets it expire,
+ we would need to do the following:
+
+ passwd -w14 -i14 fred
+
+ Now fred is changed to:
+ fred P 03/04/96 0 60 14 14
+
+ For more information on the passwd command see the online manual page.
+
+ 7.3. The login.defs file.
+
+ The file /etc/login is the configuration file for the login program
+ and also for the Shadow Suite as a whole.
+
+ /etc/login contains settings from what the prompts will look like to
+ what the default expiration will be when a user changes his password.
+
+ The /etc/login.defs file is quite well documented just by the comments
+ that are contained within it. However, there are a few things to
+ note:
+
+ · It contains flags that can be turned on or off that determine the
+ amount of logging that takes place.
+
+ · It contains pointers to other configuration files.
+
+ · It contains defaults assignments for things like password aging.
+
+ From the above list you can see that this is a rather important file,
+ and you should make sure that it is present, and that the settings are
+ what you desire for your system.
+
+ 7.4. Group passwords.
+
+ The /etc/groups file may contain passwords that permit a user to
+ become a member of a particular group. This function is enabled if
+ you define the constant SHADOWGRP in the /usr/src/shadow-
+ YYMMDD/config.h file.
+
+ If you define this constant and then compile, you must create an
+ /etc/gshadow file to hold the group passwords and the group
+ administrator information.
+
+ When you created the /etc/shadow, you used a program called pwconv,
+ there no equivalent program to create the /etc/gshadow file, but it
+ really doesn't matter, it takes care of itself.
+
+ To create the initial /etc/gshadow file do the following:
+
+ touch /etc/gshadow
+ chown root.root /etc/gshadow
+ chmod 700 /etc/gshadow
+
+ Once you create new groups, they will be added to the /etc/group and
+ the /etc/gshadow files. If you modify a group by adding or removing
+ users or changing the group password, the /etc/gshadow file will be
+ changed.
+
+ The programs groups, groupadd, groupmod, and groupdel are provided as
+ part of the Shadow Suite to modify groups.
+
+ The format of the /etc/group file is as follows:
+
+ groupname:!:GID:member,member,...
+
+ Where:
+
+ groupname
+ The name of the group
+
+ ! The field that normally holds the password, but that is now
+ relocated to the /etc/gshadow file.
+
+ GID
+ The numerical group ID number
+
+ member
+ List of group members
+
+ The format of the /etc/gshadow file is as follows:
+
+ groupname:password:admin,admin,...:member,member,...
+
+ Where:
+
+ groupname
+ The name of the group
+
+ password
+ The encoded group password.
+
+ admin
+ List of group administrators
+
+ member
+ List of group members
+
+ The command gpasswd is used only for adding or removing administrators
+ and members to or from a group. root or someone in the list of
+ administrators may add or remove group members.
+
+ The groups password can be changed using the passwd command by root or
+ anyone listed as an administrator for the group.
+
+ Despite the fact that there is not currently a manual page for
+ gpasswd, typing gpasswd without any parameters gives a listing of
+ options. It's fairly easy to grasp how it all works once you
+ understand the file formats and the concepts.
+
+ 7.5. Consistency checking programs
+
+ 7.5.1. pwck
+
+ The program pwck is provided to provide a consistency check on the
+ /etc/passwd and /etc/shadow files. It will check each username and
+ verify that it has the following:
+
+ · the correct number of fields
+
+ · unique user name
+
+ · valid user and group identifier
+
+ · valid primary group
+
+ · valid home directory
+
+ · valid login shell
+
+ It will also warn of any account that has no password.
+
+ It's a good idea to run pwck after installing the Shadow Suite. It's
+ also a good idea to run it periodically, perhaps weekly or monthly.
+ If you use the -r option, you can use cron to run it on a regular
+ basis and have the report mailed to you.
+
+ 7.5.2. grpck
+
+ grpck is the consistency checking program for the /etc/group and
+ /etc/gshadow files. It performs the following checks:
+
+ · the correct number of fields
+
+ · unique group name
+
+ · valid list of members and administrators
+
+ It also has the -r option for automated reports.
+
+ 7.6. Dial-up passwords.
+
+ Dial-up passwords are another optional line of defense for systems
+ that allow dial-in access. If you have a system that allows many
+ people to connect locally or via a network, but you want to limit who
+ can dial in and connect, then dial-up passwords are for you. To
+ enable dial-up passwords, you must edit the file /etc/login.defs and
+ ensure that DIALUPS_CHECK_ENAB is set to yes.
+
+ Two files contain the dial-up information, /etc/dialups which contains
+ the ttys (one per line, with the leading "/dev/" removed). If a tty
+ is listed then dial-up checks are performed.
+
+ The second file is the /etc/d_passwd file. This file contains the
+ fully qualified path name of a shell, followed by an optional
+ password.
+
+ If a user logs into a line that is listed in /etc/dialups, and his
+ shell is listed in the file /etc/d_passwd he will be allowed access
+ only by suppling the correct password.
+
+ Another useful purpose for using dial-up passwords might be to setup a
+ line that only allows a certain type of connect (perhaps a PPP or UUCP
+ connection). If a user tries to get another type of connection (i.e.
+ a list of shells), he must know a password to use the line.
+
+ Before you can use the dial-up feature, you must create the files.
+
+ The command dpasswd is provided to assign passwords to the shells in
+ the /etc/d_passwd file. See the manual page for more information.
+ 8. Adding shadow support to a C program
+
+ Adding shadow support to a program is actually fairly straightforward.
+ The only problem is that the program must be run by root (or SUID
+ root) in order for the the program to be able to access the
+ /etc/shadow file.
+
+ This presents one big problem: very careful programming practices must
+ be followed when creating SUID programs. For instance, if a program
+ has a shell escape, this must not occur as root if the program is SUID
+ root.
+
+ For adding shadow support to a program so that it can check passwords,
+ but otherwise does need to run as root, it's a lot safer to run the
+ program SUID shadow instead. The xlock program is an example of this.
+
+ In the example given below, pppd-1.2.1d already runs SUID as root, so
+ adding shadow support should not make the program any more vulnerable.
+
+ 8.1. Header files
+
+ The header files should reside in /usr/include/shadow. There should
+ also be a /usr/include/shadow.h, but it will be a symbolic link to
+ /usr/include/shadow/shadow.h.
+
+ To add shadow support to a program, you need to include the header
+ files:
+
+ #include <shadow/shadow.h>
+ #include <shadow/pwauth.h>
+
+ It might be a good idea to use compiler directives to conditionally
+ compile the shadow code (I do in the example below).
+
+ 8.2. libshadow.a library
+
+ When you installed the Shadow Suite the libshadow.a file was created
+ and installed in /usr/lib.
+
+ When compiling shadow support into a program, the linker needs to be
+ told to include the libshadow.a library into the link.
+
+ This is done by:
+
+ gcc program.c -o program -lshadow
+
+ However, as we will see in the example below, most large programs use
+ a Makefile, and usually have a variable called LIBS=... that we will
+ modify.
+
+ 8.3. Shadow Structure
+
+ The libshadow.a library uses a structure called spwd for the
+ information it retrieves from the /etc/shadow file. This is the
+ definition of the spwd structure from the /usr/include/shadow/shadow.h
+ header file:
+
+ ______________________________________________________________________
+ struct spwd
+ {
+ char *sp_namp; /* login name */
+ char *sp_pwdp; /* encrypted password */
+ sptime sp_lstchg; /* date of last change */
+ sptime sp_min; /* minimum number of days between changes */
+ sptime sp_max; /* maximum number of days between changes */
+ sptime sp_warn; /* number of days of warning before password
+ expires */
+ sptime sp_inact; /* number of days after password expires
+ until the account becomes unusable. */
+ sptime sp_expire; /* days since 1/1/70 until account expires
+ */
+ unsigned long sp_flag; /* reserved for future use */
+ };
+ ______________________________________________________________________
+
+ The Shadow Suite can put things into the sp_pwdp field besides just
+ the encoded passwd. The password field could contain:
+
+ username:Npge08pfz4wuk;@/sbin/extra:9479:0:10000::::
+
+ This means that in addition to the password, the program /sbin/extra
+ should be called for further authentication. The program called will
+ get passed the username and a switch that indicates why it's being
+ called. See the file /usr/include/shadow/pwauth.h and the source code
+ for pwauth.c for more information.
+
+ What this means is that we should use the function pwauth to perform
+ the actual authentication, as it will take care of the secondary
+ authentication as well. The example below does this.
+
+ The author of the Shadow Suite indicates that since most programs in
+ existence don't do this, and that it may be removed or changed in
+ future versions of the Shadow Suite.
+
+ 8.4. Shadow Functions
+
+ The shadow.h file also contains the function prototypes for the
+ functions contained in the libshadow.a library:
+
+ ______________________________________________________________________
+ extern void setspent __P ((void));
+ extern void endspent __P ((void));
+ extern struct spwd *sgetspent __P ((__const char *__string));
+ extern struct spwd *fgetspent __P ((FILE *__fp));
+ extern struct spwd *getspent __P ((void));
+ extern struct spwd *getspnam __P ((__const char *__name));
+ extern int putspent __P ((__const struct spwd *__sp, FILE *__fp));
+ ______________________________________________________________________
+
+ The function that we are going to use in the example is: getspnam
+ which will retrieve for us a spwd structure for the supplied name.
+
+ 8.5. Example
+
+ This is an example of adding shadow support to a program that needs
+ it, but does not have it by default.
+
+ This example uses the Point-to-Point Protocol Server (pppd-1.2.1d),
+ which has a mode in which it performs PAP authentication using user
+ names and passwords from the /etc/passwd file instead of the PAP or
+ CHAP files. You would not need to add this code to pppd-2.2.0 because
+ it's already there.
+
+ This feature of pppd probably isn't used very much, but if you
+ installed the Shadow Suite, it won't work anymore because the
+ passwords are no longer stored in /etc/passwd.
+
+ The code for authenticating users under pppd-1.2.1d is located in the
+ /usr/src/pppd-1.2.1d/pppd/auth.c file.
+
+ The following code needs to be added to the top of the file where all
+ the other #include directives are. We have surrounded the #includes
+ with conditional directives (i.e. only include if we are compiling for
+ shadow support).
+
+ ______________________________________________________________________
+ #ifdef HAS_SHADOW
+ #include <shadow.h>
+ #include <shadow/pwauth.h>
+ #endif
+ ______________________________________________________________________
+
+ The next thing to do is to modify the actual code. We are still
+ making changes to the auth.c file.
+
+ Function auth.c before modifications:
+
+ ______________________________________________________________________
+ /*
+ * login - Check the user name and password against the system
+ * password database, and login the user if OK.
+ *
+ * returns:
+ * UPAP_AUTHNAK: Login failed.
+ * UPAP_AUTHACK: Login succeeded.
+ * In either case, msg points to an appropriate message.
+ */
+ static int
+ login(user, passwd, msg, msglen)
+ char *user;
+ char *passwd;
+ char **msg;
+ int *msglen;
+ {
+ struct passwd *pw;
+ char *epasswd;
+ char *tty;
+
+ if ((pw = getpwnam(user)) == NULL) {
+ return (UPAP_AUTHNAK);
+ }
+ /*
+ * XXX If no passwd, let them login without one.
+ */
+ if (pw->pw_passwd == '\0') {
+ return (UPAP_AUTHACK);
+ }
+
+ epasswd = crypt(passwd, pw->pw_passwd);
+ if (strcmp(epasswd, pw->pw_passwd)) {
+ return (UPAP_AUTHNAK);
+ }
+
+ syslog(LOG_INFO, "user %s logged in", user);
+
+ /*
+ * Write a wtmp entry for this user.
+ */
+ tty = strrchr(devname, '/');
+ if (tty == NULL)
+ tty = devname;
+ else
+ tty++;
+ logwtmp(tty, user, ""); /* Add wtmp login entry */
+ logged_in = TRUE;
+
+ return (UPAP_AUTHACK);
+ }
+ ______________________________________________________________________
+
+ The user's password is placed into pw->pw_passwd, so all we really
+ need to do is add the function getspnam. This will put the password
+ into spwd->sp_pwdp.
+
+ We will add the function pwauth to perform the actual authentication.
+ This will automatically perform secondary authentication if the shadow
+ file is setup for it.
+
+ Function auth.c after modifications to support shadow:
+
+ ______________________________________________________________________
+ /*
+ * login - Check the user name and password against the system
+ * password database, and login the user if OK.
+ *
+ * This function has been modified to support the Linux Shadow Password
+ * Suite if USE_SHADOW is defined.
+ *
+ * returns:
+ * UPAP_AUTHNAK: Login failed.
+ * UPAP_AUTHACK: Login succeeded.
+ * In either case, msg points to an appropriate message.
+ */
+ static int
+ login(user, passwd, msg, msglen)
+ char *user;
+ char *passwd;
+ char **msg;
+ int *msglen;
+ {
+ struct passwd *pw;
+ char *epasswd;
+ char *tty;
+
+ #ifdef USE_SHADOW
+ struct spwd *spwd;
+ struct spwd *getspnam();
+ #endif
+
+ if ((pw = getpwnam(user)) == NULL) {
+ return (UPAP_AUTHNAK);
+ }
+
+ #ifdef USE_SHADOW
+ spwd = getspnam(user);
+ if (spwd)
+ pw->pw_passwd = spwd->sp-pwdp;
+ #endif
+
+ /*
+ * XXX If no passwd, let NOT them login without one.
+ */
+ if (pw->pw_passwd == '\0') {
+ return (UPAP_AUTHNAK);
+ }
+ #ifdef HAS_SHADOW
+ if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
+ && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
+ || !valid (passwd, pw)) {
+ return (UPAP_AUTHNAK);
+ }
+ #else
+ epasswd = crypt(passwd, pw->pw_passwd);
+ if (strcmp(epasswd, pw->pw_passwd)) {
+ return (UPAP_AUTHNAK);
+ }
+ #endif
+
+ syslog(LOG_INFO, "user %s logged in", user);
+
+ /*
+ * Write a wtmp entry for this user.
+ */
+ tty = strrchr(devname, '/');
+ if (tty == NULL)
+ tty = devname;
+ else
+ tty++;
+ logwtmp(tty, user, ""); /* Add wtmp login entry */
+ logged_in = TRUE;
+
+ return (UPAP_AUTHACK);
+ }
+ ______________________________________________________________________
+
+ Careful examination will reveal that we made another change as well.
+ The original version allowed access (returned UPAP_AUTHACK if there
+ was NO password in the /etc/passwd file. This is not good, because a
+ common use of this login feature is to use one account to allow access
+ to the PPP process and then check the username and password supplied
+ by PAP with the username in the /etc/passwd file and the password in
+ the /etc/shadow file.
+
+ So if we had set the original version up to run as the shell for a
+ user i.e. ppp, then anyone could get a ppp connection by setting
+ their PAP to user ppp and a password of null.
+
+ We fixed this also by returning UPAP_AUTHNAK instead of UPAP_AUTHACK
+ if the password field was empty.
+
+ Interestingly enough, pppd-2.2.0 has the same problem.
+
+ Next we need to modify the Makefile so that two things occur:
+ USE_SHADOW must be defined, and libshadow.a needs to be added to the
+ linking process.
+
+ Edit the Makefile, and add:
+
+ LIBS = -lshadow
+
+ Then we find the line:
+
+ COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t
+
+ And change it to:
+
+ COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t -DUSE_SHADOW
+
+ Now make and install.
+
+ 9. Frequently Asked Questions.
+
+ Q: I used to control which tty's root could log into using the file
+ /etc/securettys, but it doesn't seem to work anymore, what's going on?
+
+ A: The file /etc/securettys does absolutely nothing now that the
+ Shadow Suite is installed. The tty's that root can use are now
+ located in the login configuration file /etc/login.defs. The entry in
+ this file may point to another file.
+
+ Q: I installed the Shadow Suite, but now I can't login, what did I
+ miss?
+
+ A: You probably installed the Shadow programs, but didn't run pwconv
+ or you forgot to copy /etc/npasswd to /etc/passwd and /etc/nshadow to
+ /etc/shadow. Also, you may need to copy login.defs to /etc.
+
+ Q: In the section on xlock, it said to change the group ownership of
+ the /etc/shadow file to shadow. I don't have a shadow group, what do
+ I do?
+
+ A: You can add one. Simply edit the /etc/group file, and insert a
+ line for the shadow group. You need to ensure that the group number
+ is not used by another group, and you need to insert it before the
+ nogroup entry. Or you can simply suid xlock to root.
+
+ Q: Is there a mailing list for the Linux Shadow Password Suite?
+
+ A: Yes, but it's for the development and beta testing of the next
+ Shadow Suite for Linux. You can get added to the list by mailing to:
+ shadow-list-request@neptune.cin.net with a subject of: subscribe. The
+ list is actually for discussions of the Linux shadow-YYMMSS series of
+ releases. You should join if you want to get involved in further
+ development or if you install the Suite on your system and want to get
+ information on newer releases.
+
+ Q: I installed the Shadow Suite, but when I use the userdel command, I
+ get "userdel: cannot open shadow group file", what did I do wrong?
+
+ A: You compiled the Shadow Suite with the SHADOWGRP option enabled,
+ but you don't have an /etc/gshadow file. You need to either edit the
+ config.h file and recompile, or create an /etc/group file. See the
+ section on shadow groups.
+
+ Q: I installed the Shadow Suite but now I'm getting encoded passwords
+ back in my /etc/passwd file, what's wrong?
+
+ A: You either enabled the AUTOSHADOW option in the Shadow config.h
+ file, or your libc was compiled with the SAHDOW_COMPAT option. You
+ need to determine which is the problem, and recompile.
+
+ 10. Copyright Message.
+
+ The Linux Shadow Password HOWTO is Copyright (c) 1996 Michael H.
+ Jackson.
+
+ Permission is granted to make and distribute verbatim copies of this
+ document provided the copyright notice and this permission notice are
+ preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of this
+ document under the conditions for verbatim copies above, provided a
+ notice clearly stating that the document is a modified version is also
+ included in the modified document.
+
+ Permission is granted to copy and distribute translations of this
+ document into another language, under the conditions specified above
+ for modified versions.
+
+ Permission is granted to convert this document into another media
+ under the conditions specified above for modified versions provided
+ the requirement to acknowledge the source document is fulfilled by
+ inclusion of an obvious reference to the source document in the new
+ media. Where there is any doubt as to what defines 'obvious' the
+ copyright owner reserves the right to decide.
+
+ 11. Miscellaneous and Acknowledgments.
+
+ The code examples for auth.c are taken from pppd-1.2.1d and
+ ppp-2.1.0e, Copyright (c) 1993 and The Australian National University
+ and Copyright (c) 1989 Carnegie Mellon University.
+
+ Thanks to Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl> for
+ writing and maintaining the Shadow Suite for Linux, and for his review
+ and comments on this document.
+
+ Thanks to Ron Tidd <rtidd@tscnet.com> for his helpful review and
+ testing.
+
+ Thanks to everyone who has sent me feedback to help improve this
+ document.
+
+ Please, if you have any comments or suggestions then mail them to me.
+
+ regards
+
+ Michael H. Jackson <mhjack@tscnet.com>
+
diff --git a/current/doc/INSTALL b/current/doc/INSTALL
new file mode 100644
index 00000000..3b50ea95
--- /dev/null
+++ b/current/doc/INSTALL
@@ -0,0 +1,176 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes a while. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/current/doc/LICENSE b/current/doc/LICENSE
new file mode 100644
index 00000000..718fbbb3
--- /dev/null
+++ b/current/doc/LICENSE
@@ -0,0 +1,118 @@
+NOTE:
+ This license has been obsoleted by the change to the BSD-style copyright.
+ You may continue to use this license if you wish, but you are under no
+ obligation to do so.
+
+(*
+This document is freely plagiarised from the 'Artistic Licence',
+distributed as part of the Perl v4.0 kit by Larry Wall, which is
+available from most major archive sites. I stole it from CrackLib.
+
+ $Id: LICENSE,v 1.2 1997/05/01 23:14:30 marekm Exp $
+*)
+
+This documents purpose is to state the conditions under which this
+Package (See definition below) viz: "Shadow", the Shadow Password Suite
+which is held by Julianne Frances Haugh, may be copied, such that the
+copyright holder maintains some semblance of artistic control over the
+development of the package, while giving the users of the package the
+right to use and distribute the Package in a more-or-less customary
+fashion, plus the right to make reasonable modifications.
+
+So there.
+
+***************************************************************************
+
+Definitions:
+
+
+A "Package" refers to the collection of files distributed by the
+Copyright Holder, and derivatives of that collection of files created
+through textual modification, or segments thereof.
+
+"Standard Version" refers to such a Package if it has not been modified,
+or has been modified in accordance with the wishes of the Copyright
+Holder.
+
+"Copyright Holder" is whoever is named in the copyright or copyrights
+for the package.
+
+"You" is you, if you're thinking about copying or distributing this
+Package.
+
+"Reasonable copying fee" is whatever you can justify on the basis of
+media cost, duplication charges, time of people involved, and so on.
+(You will not be required to justify it to the Copyright Holder, but
+only to the computing community at large as a market that must bear the
+fee.)
+
+"Freely Available" means that no fee is charged for the item itself,
+though there may be fees involved in handling the item. It also means
+that recipients of the item may redistribute it under the same
+conditions they received it.
+
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated
+disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way,
+provided that you insert a prominent notice in each changed file stating
+how and when AND WHY you changed that file, and provided that you do at
+least ONE of the following:
+
+a) place your modifications in the Public Domain or otherwise make them
+Freely Available, such as by posting said modifications to Usenet or an
+equivalent medium, or placing the modifications on a major archive site
+such as uunet.uu.net, or by allowing the Copyright Holder to include
+your modifications in the Standard Version of the Package.
+
+b) use the modified Package only within your corporation or organization.
+
+c) rename any non-standard executables so the names do not conflict with
+standard executables, which must also be provided, and provide separate
+documentation for each non-standard executable that clearly documents
+how it differs from the Standard Version.
+
+d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+a) distribute a Standard Version of the executables and library files,
+together with instructions (in the manual page or equivalent) on where
+to get the Standard Version.
+
+b) accompany the distribution with the machine-readable source of the
+Package with your modifications.
+
+c) accompany any non-standard executables with their corresponding
+Standard Version executables, giving the non-standard executables
+non-standard names, and clearly documenting the differences in manual
+pages (or equivalent), together with instructions on where to get the
+Standard Version.
+
+d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this Package.
+YOU MAY NOT CHARGE A FEE FOR THIS PACKAGE ITSELF. However, you may
+distribute this Package in aggregate with other (possibly commercial)
+programs as part of a larger (possibly commercial) software distribution
+provided that YOU DO NOT ADVERTISE this package as a product of your
+own.
+
+6. The name of the Copyright Holder may not be used to endorse or
+promote products derived from this software without specific prior
+written permission.
+
+7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ The End
diff --git a/current/doc/LSM b/current/doc/LSM
new file mode 100644
index 00000000..75a215e1
--- /dev/null
+++ b/current/doc/LSM
@@ -0,0 +1,20 @@
+Begin3
+Title: Shadow Password Suite
+Version: 20000902
+Entered-date: 02SEP00
+Description: Shadow password file utilities. This package includes
+ the programs necessary to convert traditional V7 UNIX
+ password files to the SVR4 shadow password format, and
+ additional tools to maintain password and group files
+ (that work with both shadow and non-shadow passwords).
+Keywords: login passwd security shadow
+Author: jfh@austin.ibm.com (Julianne F. Haugh)
+Maintained-by: kloczek@rudy.mif.pg.gda.pl (Tomasz Kloczko)
+ marekm@linux.org.pl (Marek Michalkiewicz) - previous maintainer
+Primary-site: piast.t19.ds.pwr.wroc.pl /pub/linux/shadow/
+ 718K shadow-20000902.tar.gz
+Alternate-site: ftp.ists.pwr.wroc.pl /pub/linux/shadow/
+Original-site: ftp.uu.net ?
+Platforms: Linux, SunOS, ...
+Copying-policy: FRS
+End
diff --git a/current/doc/Makefile.am b/current/doc/Makefile.am
new file mode 100644
index 00000000..487677a0
--- /dev/null
+++ b/current/doc/Makefile.am
@@ -0,0 +1,7 @@
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+EXTRA_DIST = ANNOUNCE CHANGES HOWTO LICENSE LSM README README.debian \
+ README.limits README.linux README.mirrors README.nls README.pam \
+ README.platforms README.shadow-paper README.sun4 \
+ WISHLIST console.c.spec.txt cracklib26.diff
diff --git a/current/doc/Makefile.in b/current/doc/Makefile.in
new file mode 100644
index 00000000..b4ee0917
--- /dev/null
+++ b/current/doc/Makefile.in
@@ -0,0 +1,212 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+EXTRA_DIST = ANNOUNCE CHANGES HOWTO LICENSE LSM README README.debian README.limits README.linux README.mirrors README.nls README.pam README.platforms README.shadow-paper README.sun4 WISHLIST console.c.spec.txt cracklib26.diff
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = README INSTALL Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/doc/README b/current/doc/README
new file mode 100644
index 00000000..c177638f
--- /dev/null
+++ b/current/doc/README
@@ -0,0 +1,253 @@
+[ $Id: README,v 1.4 2000/08/26 18:27:09 marekm Exp $ ]
+
+This is the explanatory document for Julianne Frances Haugh's login
+replacement, release 3. This document was last updated 16 Feb 1997.
+
+This software is copyright 1988 - 1997, Julianne F. Haugh. All rights
+reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+This source code is currently archived on ftp.uu.net in the
+comp.sources.misc portion of the USENET archives. You may also contact
+the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have any questions
+regarding this package.
+
+THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL
+LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE
+FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO
+OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS
+ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL
+LOSS OF INFORMATION OR MACHINE RESOURCES.
+
+Special thanks are due to Chip Rosenthal for his fine testing efforts;
+to Steve Simmons for his work in porting this code to BSD; and to Bill
+Kennedy for his contributions of LaserJet printer time and energies.
+Also, thanks for Dennis L. Mumaugh for the initial shadow password
+information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System
+V Release 4 changes. Effort in porting to SunOS has been contributed
+by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr.
+(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release
+4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au).
+Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl)
+for taking over the Linux port of this software.
+
+New for Release 3.3:
+ User-defined authentication has been added. This allows you to
+ write programs to replace the password authentication method
+ which uses the crypt() function.
+
+ The CrackLib password checking library is supported as of release
+ 3.3.0. It allows you to perform pro-active password checking as
+ each password is changed.
+
+Warning:
+ The newuser command will be removed in a later release.
+ The libsec.a library will be removed at some point after
+ version 3.3.3.
+
+This software is described in the 3rd USENIX Security Symposium
+proceedings. These proceedings are available from
+
+ USENIX Association
+ 2560 Ninth Street, Suite 215
+ Berkeley, CA 94710
+
+The current price is $30 for USENIX members and $39 for non-members.
+
+Begin by reading and editing the config.h file. All options are selected
+by using #define's. A brief description for each available option appears
+below. You may want to print this file out as it is LONG and you will
+need to refer to it while editting config.h. You will also have to edit
+the Makefile. The possible differences are documented there. Pay close
+attention to the install: rule. Login now runs on about 30 different
+varieties of UNIX that I have been made aware of. If you have any qualms,
+you should run "make save" before running "make install". If something
+breaks you can use "make restore" to put things back. In any case, you
+should have a recent system backup as the potential for serious damage
+exists.
+
+There are special Makefile and config.h files for SVR4, SunOS 4.1, and
+Linux systems. If there is a major UNIX variant that you would like to
+see supported, please send working Makefile and config.h files and I will
+try to include then in the base distribution.
+
+Note that there are MANY options. As distributed most options are turned
+on, which produces a really nice package. This is the system as used on
+some of the authors' machines. There are many options which may be
+selected at run time. You should refer to the login.5 manual page for
+more information regarding these options.
+
+There are several files which you may have to replace. If your system has
+a lastlog.h file, you should replace the one which I provide with your
+system version. The pwd.h file that is produced by "make" must agree
+exactly with the system supplied version. You should re-arrange the
+fields or #define's until they match. The same is true for "shadow.h",
+if you system provides one. You may want to replace large portions of
+that file (or the entire file) with your system version. It is provided
+for those systems which do NOT provide /usr/include/shadow.h. If you
+do not have a the crypt() function in your library (perhaps because you
+are located outside the United States), you may wish to look into the
+UFC-crypt package which was posted to comp.sources.misc in volume 23,
+issues 97 and 98.
+
+Login Defaults File -
+ This option selects the name of the file to read for the
+ run-time configurable options. The default value for
+ LOGINDEFS is "/etc/login.defs".
+
+Shadow [ unreadable ] Password Files -
+ This option utilizes an alternate, non-readable file to
+ contain the actual encrypted passwords. This is presumed
+ to increase system security by increasing the difficulty
+ with which system crackers obtain encrypted passwords.
+
+ Select this option by defining the SHADOWPWD macro.
+
+ This feature is optional, but only certain commands may
+ be compiled with this option disabled.
+
+Shadow Group Files -
+ This option utilizes an alternate, non-readable file to
+ contain encrypted group passwords and group administrator
+ information.
+
+ This feature allows one or more users to be defined as
+ the administrators of a group for the purpose of adding
+ or deleting members and changing the group password.
+
+ Select this option by defining the SHADOWGRP macro. You
+ must also create an emptry /etc/gshadow file. You must
+ select the SHADOWPWD option if you select SHADOWGRP.
+
+DBM Password Files -
+ This option utilizes the DBM database access routines to
+ increase the performance of user name and ID lookups in the
+ password file. You may select the NDBM database instead
+ and have DBM-style access to all user information files.
+
+ Select this option by defining both the DBM and GETPWENT
+ macros. The FGETPWENT macro must also be defined or the
+ fgetpwent() library routine must be present.
+
+Double Length Passwords -
+ This option extends the maximum length of a user password
+ to 16 characters from eight.
+
+ Select this option by defining the DOUBLESIZE macro.
+ Credit for this option is due Jonathan Bayer.
+
+Password Aging -
+ This option includes code to perform password aging.
+ Password aging is presumed to increase system security
+ by forcing users to change passwords on a regular
+ basis. The resolution on password age is in weeks for
+ non-shadow password systems and in days otherwise.
+
+ Select this option by defining the AGING macro.
+
+Syslog -
+ This option causes the code to log various errors or
+ special conditions to the syslog daemon. The types of
+ information that are logged security violations, changes
+ to the user database, and program errors.
+
+ Select syslog processing by defining the USE_SYSLOG
+ macro.
+
+Remote Login -
+ This option causes certain network login code to be
+ inserted to enable the "rlogin" and "telnet" commands to
+ work. To enable network logins, define the RLOGIN macro.
+ If your <utmp.h> file includes a ut_host member, you must
+ also define the UT_HOST macro. Note that SVR4 has a
+ "utmpx" file to hold the ut_host member, so UT_HOST is
+ not required.
+
+Directory Reading Routines -
+ Three different macros are defined for opening and reading
+ directories. They are DIR_XENIX, DIR_BSD, and DIR_SYSV.
+ Refer to config.h for more details.
+
+Library Configuration Macros -
+ The following macros define the functions which are present
+ in your system library:
+
+ HAVE_ULIMIT - Define if your UNIX supports ulimit()
+ GETPWENT - Define if you want my GETPWENT(3) routines
+ GETGRENT - Define if you want my GETGRENT(3) routines
+ NEED_AL64 - Define if library does not include a64l()
+ NEED_MKDIR - Define if system does not have mkdir()
+ NEED_RMDIR - Define if system does not have rmdir()
+ NEED_RENAME - Define if system does not have rename()
+ NEED_STRSTR - Define if library does not include strstr()
+
+Password File Information -
+ The following macros define the fields which are present in
+ your system password file. Because the system was compiled
+ to use the password file in its original form, these macros
+ must agree with the actual contents of the file.
+
+ BSD_QUOTA - the pw_quota field exists
+ ATT_AGE - the pw_age field exists
+ ATT_COMMENT - the pw_comment field exists
+
+Signal Return Type -
+ Because different systems return different data types for
+ the signal() system call, you must define SIGTYPE to be
+ the data type your system uses. The default is "int", but
+ "void" is another popular value.
+
+SunOS 4.1.1 Notes: (mke@kaberd.rain.com) Michael J. Miller Jr.
+
+[ These notes were edited from the original. The standard Makefile
+ and config.h have notes indicating the changes required for SunOS.
+ Steve Allen at Lick has been working on cleaning up this platform. ]
+
+You'll need to do the following to get the shadow password dist to
+compile on a sun 4.1.1 system.
+
+If using csh, then type 'rehash'. cd to the /etc directory and type
+'pwconv'. This will create two files, nshadow and npasswd.
+now type 'mkpasswd -f nshadow' and 'mkpasswd -f npasswd'. This will
+create the shadow password file.
+
+Note: ftp will still use the old password file. Modified versions of
+ ftpd are available, or you may modify the version of ftpd from
+ any of the freely redistributable ftpd clones.
+
+Note: If you run suns pcnfs, be aware that it will still be looking at the
+ old password file as well. I may work out a patch for this, as I am
+ fairly certain the stuff on the sun side comes with source.
+
+Note: I have compiled this package with the standard c compiler and
+ suns unbundled c compiler at an optomization level of 2 in
+ both casses. Haven't tried gcc yet, so I don't know wether it
+ works. Same goes for suns C++ compiler.
+
+Note: Has been compiled on a sun 3/75 running sunos 4.1.1. Should compile
+ fine on sun 4's running 4.1.1, and may compile on suns running
+ 4.1. Have no idea what sort of success people will have that
+ are running 4.03 and older versions.
diff --git a/current/doc/README.debian b/current/doc/README.debian
new file mode 100644
index 00000000..43b749be
--- /dev/null
+++ b/current/doc/README.debian
@@ -0,0 +1,68 @@
+Read this file first for a brief overview of the new versions of login
+and passwd.
+
+
+---Shadow passwords
+
+The command `shadowconfig on' will turn on shadow password support.
+`shadowconfig off' will turn it back off. If you turn on shadow
+password support, you'll gain the ability to set password ages and
+expirations with chage(1).
+
+You may want to install the secure-su package which allows more
+restrictions on su, for example a wheel group.
+
+
+---General configuration
+
+Most of the configuration for the shadow utilities is in
+/etc/login.defs. See login.defs(5). The defaults are quite
+reasonable.
+
+
+---MD5 Encryption
+
+If you set MD5_CRYPT_ENAB=yes in /etc/login.defs, passwords will be
+encrypted with an MD5-based algorithm. It also supports of passwords
+of unlimited length and longer salt strings.
+
+
+---Login and resource control
+
+/etc/login.access and /etc/porttime control who may login to which
+ports and when they may login. To enforce time restrictions, you'll
+need to run logoutd. /etc/init.d/logoutd will start it on bootup if
+there are non-comment lines in /etc/portttime.
+
+The lastlog and faillog commands will report the last time a user had
+a successful and failed login, respectively.
+
+You may set per-user resource limits by editing /etc/limits. See
+limits(5).
+
+
+---Adding users and groups
+
+Though you may add users and groups with the SysV type commands,
+useradd and groupadd, I recommend you add them with Debian adduser
+version 3+. adduser gives you more configuration and conforms to the
+Debian UID and GID allocation.
+
+Editing user and group parameters can be done with usermod and
+groupmod. Removing users and groups can be done with userdel and
+groupdel.
+
+
+--- Group administration
+
+Local group allocation is much easier. With gpasswd(1) you can
+designate users to administer groups. They can then securely add or
+remove users from the group.
+
+
+--- What to read next?
+
+Read the manpages, the other files in this directory, and the Shadow
+Password HOWTO (included in the doc-linux package). A large portion
+of these files deals with getting shadow installed. You can, of
+course, ignore those parts.
diff --git a/current/doc/README.limits b/current/doc/README.limits
new file mode 100644
index 00000000..6551ad72
--- /dev/null
+++ b/current/doc/README.limits
@@ -0,0 +1,66 @@
+
+ABOUT shadow-login limits:
+
+This code is merged into shadow login program from the original LShell 2.01
+written by Joel Katz. The port and some additional features have been added
+by Cristian Gafton (gafton@sorosis.ro).
+
+
+Changes:
+ - 96/04/16
+ - {spaces,tabs} allowed within limits string
+ - Warn via syslog multiple default limits
+ - added few paragraphs to the login man page
+ - 96/04/14
+ - code merged into lmain.c --cristiang
+
+TODO: - support groups in the limits file
+ (only usernames are supported at this momment :-( )
+
+Setting user limits for shadow login program
+
+First, make a root-only-readable file (/etc/limits by default or LIMITS_FILE
+defined config.h) that describes the resource limits you wish to impose. By
+default no quotas are imposed on 'root'. In fact, there is no way to impose
+limits via this procedure to root-equiv accounts (accounts with UID 0).
+
+Each line describes a limit for a user in the form:
+
+ user LIMITS_STRING
+
+The LIMITS_STRING is a string of a concatenated list of resource limits.
+Each limit consists of a letter identifier followed by a numerical limit.
+The valid identifiers are:
+
+ A: max address space (KB)
+ C: max core file size (KB)
+ D: max data size (KB)
+ F: maximum filesize (KB)
+ M: max locked-in-memory address space (KB)
+ N: max number of open files
+ R: max resident set size (KB)
+ S: max stack size (KB)
+ T: max CPU time (MIN)
+ U: max number of processes
+ L: max number of logins for this user
+
+For example, L2D2048N5 is a valid LIMITS_STRING. For reading convenience,
+the following entries are equivalent:
+
+username L2D2048N5
+username L2 D2048 N5
+
+Be aware that after <username> the rest of the line is considered a limit
+string, thus comments are not allowed. A invalid limits string will be
+rejected (not considered) by the login program.
+
+The default entry is denoted by username '*'. If you have multiple 'default'
+entries in your LIMITS_FILE, then the last one will be used as the default
+entry.
+
+To completely disable limits for a user, a single dash (-) will do.
+
+Also, please note that all limit settings are set PER LOGIN. They are
+not global, nor are they permanent. Perhaps global limits will come, but
+for now this will have to do ;)
+
diff --git a/current/doc/README.linux b/current/doc/README.linux
new file mode 100644
index 00000000..cd55c940
--- /dev/null
+++ b/current/doc/README.linux
@@ -0,0 +1,166 @@
+$Id: README.linux,v 1.20 2000/08/26 18:27:09 marekm Exp $
+
+This is the shadow suite hacked a bit for Linux. See CHANGES for
+short description of changes. See also WISHLIST if you have too
+much time on your hands :-). Now that copyright issues have been
+resolved, the most important thing is testing. Please test this
+code as much as you can, and report any problems. At this point,
+I made so many changes that any bugs are probably mine.
+
+This package uses GNU autoconf, so it should be quite portable
+- but it hasn't been tested much on anything but Linux/x86.
+Long time ago, it has been reported to work on SunOS 4.1.x,
+and recently there has been some success on Solaris 2.x and Irix.
+I'd like to compile a current list of platforms this package is
+known to work on - if you get it to work on some new OS (non-x86
+Linux, or non-Linux), please let me know. Please specify: host
+type guessed by autoconf, libc version, distribution, changes
+you needed to make (if any), etc. Please see README.platforms
+for the current (incomplete - I know there are more...) list of
+platforms this package is known to work on.
+
+There is a developers mailing list. It has moved again, and is
+now hosted by SuSE - thanks to Thorsten Kukuk <kukuk@suse.de>.
+Send the command "subscribe shadow" to majordomo@suse.com to
+subscribe if you are interested. To send mail to everyone on
+the list, send it to shadow@suse.com.
+
+Before reporting bugs, please check if they still exist in my latest
+development snapshot. Every few weeks I make a new version available
+at the following URLs:
+ftp://piast.t19.ds.pwr.wroc.pl/pub/linux/shadow/
+ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/
+http://www.itnet.pl/amelektr/linux/shadow/
+(there are also mirror sites, see README.mirrors).
+
+After installation, please remember to remove any old binaries like
+/bin/passwd (this version installs /usr/bin/passwd). If your passwd
+program doesn't like the new /etc/login.defs settings, and complains
+about "configuration error", this is most likely the problem.
+
+Current versions of the Linux C library (both libc 5.x and glibc 2.x)
+have the shadow support, including MD5-based crypt(), built in.
+Because of this, libshadow.a will build without these functions,
+and the ones from libc will be used instead. Currently, libshadow.a
+is for internal use only, so if you see -lshadow in a Makefile of
+some other package, it is safe to remove it.
+
+Remember that shadow passwords will not make your system more secure
+if your distribution has gaping holes which let any user become root.
+Some distributions, especially the older ones, are much like SunOS 4.1
+without any security patches installed :-). Read the linux-security
+mailing list archives, and plug all holes before attempting to install
+the shadow suite.
+
+Very old versions of this package (shadow-3.3.x, shadow-mk) had a few
+nasty security holes, too. Please use the latest version if possible.
+
+Encrypted passwords are not readable, but it is highly recommended
+to use cracklib with a big dictionary to prevent users from choosing
+weak passwords. This way if someone ever gets access to /etc/shadow
+(for example, because of some not yet discovered bug), they will not
+get half of the passwords using Crack... There is a configure option
+to use cracklib, I haven't tested it myself but I'm told it works.
+
+The code feels like stabilizing now - while still BETA, it should
+work quite well. Many bugs have been fixed, but there may be still
+a few lurking. Again, please test it and report any problems.
+
+Thanks to Julianne Frances Haugh <jfh@austin.ibm.com> who wrote the thing
+in the first place, sent me the latest version, and released it under
+a "free" BSD-style license, so that it can be included in Linux
+distributions (at least Debian 1.3 and Slackware 3.2 are already
+doing that; Debian and Red Hat packaging standards are supported in
+the standard source tree). David Frey <David.Frey@lugs.ch>, Michael
+Meskes <meskes@topsystem.de> and Guy Maor <maor@debian.org> have
+done a lot of work to integrate shadow passwords into Debian Linux.
+
+Ben Collins <bcollins@debian.org> maintains this package for Debian
+and added complete PAM support, now available in Debian 2.2.
+
+Thanks to Bradley Glonka <bradley@123.net> of Linux System Labs
+(http://www.lsl.com/) for sending me a free Red Hat 4.2 CD-ROM,
+making it possible to test this package on this distribution.
+
+Special thanks to Michael H. Jackson <mhjack@tscnet.com> who wrote
+the Linux Shadow Password HOWTO. Special thanks to Greg Gallagher
+<ggallag@orion.it.luc.edu> and Jon Lewis for maintaining the
+developers mailing list for a long time.
+
+Thanks to Maciej 'Tycoon' Majchrowski <tycoon@piast.t19.ds.pwr.wroc.pl>
+for ftp server space on piast.t19.ds.pwr.wroc.pl, and to Pawel Wiecek
+<coven@pwr.wroc.pl> for keeping bach.ists.pwr.wroc.pl up and running.
+
+Ian Jackson <iwj10@cus.cam.ac.uk> criticized the current shadow password
+system (see the linux-security mailing list archives). We disagree on
+some points, but this started a discussion on possible better solutions.
+Theodore Ts'o <tytso@mit.edu> has started a new project to implement
+Pluggable Authentication Modules - a relatively new standard API which
+makes it easier to add new authentication mechanisms (it's more than
+just shadow passwords). See http://parc.power.net/morgan/Linux-PAM/ for
+more information. (XXX - this URL has changed, I have to check where
+PAM is now... -MM)
+
+Thanks to at least the following people for sending me patches, bug
+reports and various comments. This list may be incomplete, I received
+a lot of mail...
+
+John Adelsberger <jja@umr.edu>
+Martin Bene <mb@sime.com>
+Luca Berra <bluca@www.polimi.it>
+Darcy Boese <possum@chardonnay.niagara.com>
+Judd Bourgeois <shagboy@bluesky.net>
+Ulisses Alonso Camaro <ulisses@pusa.eleinf.uv.es>
+Ed Carp <ecarp@netcom.com>
+Rani Chouha <ranibey@smartec.com>
+Ben Collins <bcollins@debian.org>
+Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
+Alan Curry <pacman@tardis.mars.net>
+Frank Denis <j@4u.net>
+Hrvoje Dogan <hdogan@bjesomar.srce.hr>
+Chris Evans <lady0110@sable.ox.ac.uk>
+Marc Ewing <marc@redhat.com>
+Janos Farkas <chexum@bankinf.banki.hu>
+Werner Fink <werner@suse.de>
+Floody <flood@evcom.net>
+David Frey <David.Frey@lugs.ch>
+Brian R. Gaeke <brg@dgate.org>
+Cristian Gafton <gafton@sorosis.ro>
+Anton Gluck <gluc@midway.uchicago.edu>
+Dave Hagewood <admin@arrowweb.com>
+Jonathan Hankins <jhankins@mailserv.homewood.k12.al.us>
+Juergen Heinzl <unicorn@noris.net>
+Joey Hess <joey@kite.ml.org>
+Tim Hockin <thockin@eagle.ais.net>
+David A. Holland <dholland@hcs.harvard.edu>
+Andreas Jaeger <aj@arthur.rhein-neckar.de>
+Timo Karjalainen <timok@iki.fi>
+Calle Karlsson <ckn@kash.se>
+Sami Kerola <kerolasa@rocketmail.com>
+Thorsten Kukuk <kukuk@suse.de>
+Jon Lewis <jlewis@lewis.org>
+Pavel Machek <pavel@bug.ucw.cz>
+Guy Maor <maor@debian.org>
+Martin Mares <mj@gts.cz>
+Rafal Maszkowski <rzm@torun.pdi.net>
+Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
+Michael Meskes <meskes@topsystem.de>
+Arkadiusz Miskiewicz <misiek@pld.org.pl>
+Greg Mortensen <loki@world.std.com>
+Mike Pakovic <mpakovic@users.southeast.net>
+Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
+Adam Rudnicki <adam@v-lo.krakow.pl>
+Algis Rudys <arudys@rice.edu>
+Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
+Jay Soffian <jay@lw.net>
+Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
+Juha Virtanen <jiivee@iki.fi>
+Michael Talbot-Wilson <mike@calypso.bns.com.au>
+Jesse Thilo <Jesse.Thilo@pobox.com>
+Shane Watts <shane@nexus.mlckew.edu.au>
+Alexander O. Yuriev <alex@bach.cis.temple.edu>
+Leonard N. Zubkoff <lnz@dandelion.com>
+
+If you want to be added here, or your e-mail address changes,
+please let me know. Thanks.
+-- Marek Michalkiewicz <marekm@linux.org.pl>
diff --git a/current/doc/README.mirrors b/current/doc/README.mirrors
new file mode 100644
index 00000000..ddc96115
--- /dev/null
+++ b/current/doc/README.mirrors
@@ -0,0 +1,60 @@
+Primary sites for the Shadow Password Suite for Linux:
+
+ftp://piast.t19.ds.pwr.wroc.pl/pub/linux/shadow/
+ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/
+http://www.itnet.pl/amelektr/linux/shadow/
+
+I upload latest versions here (and sometimes also to sunsite, but not
+every new release). If you are not in Poland, these sites may be slow
+for you - please use a mirror near you.
+
+Thanks to several people who offered to mirror this archive. Mirror
+sites known to me (with addresses of people who submitted them to
+this list) are listed below. If you want your site to be added here,
+please let me know (specify the URL, and contact e-mail address).
+If any of these sites become way out of date and should be removed,
+or if they are good but the URL changes, please let me know too.
+
+Working mirrors that I know of, sorted by country (note: I removed
+a few mirrors that didn't work when I tried to access them several
+times - if any of them are still alive, please let me know):
+
+(XXX - list may be out of date now.)
+
+Brazil:
+
+ ftp://ftp.athena.pads.ufrj.br/pub/linux/shadow/
+ Rafael Jorge Csura Szendrodi <szendro@santuario.pads.ufrj.br>
+
+Czech Republic:
+
+ ftp://ftp.gts.cz/pub/linux/security/shadow/
+ Martin Mares <mj@mj.gts.cz>
+
+Greece:
+
+ ftp://linux.forthnet.gr/pub/linux/shadow/
+ http://linux.forthnet.gr/pub/linux/shadow/
+ Sotiris Tsimbonis <stsimb@forthnet.gr>
+
+Poland:
+
+ ftp://xenium.pdi.net/pub/Crypto/shadow/
+ Marcin E. Bednarz <specula@pdi.net>
+
+ ftp://giswitch.sggw.waw.pl/pub/Linux/shadow/
+ Marek Czajko <mcj@giswitch.sggw.waw.pl>
+
+Romania:
+
+ ftp://ftp.kappa.ro/pub/Linux/Security/shadow/
+ Mircea Damian <dmircea@kappa.ro>
+
+United States:
+
+ ftp://ftp.cqc.com/pub/mirrors/linux-shadow/
+ pacman@cqc.com
+
+Thanks,
+Marek Michalkiewicz <marekm@linux.org.pl>
+(or marekm@piast.t19.ds.pwr.wroc.pl, or marekm@bach.ists.pwr.wroc.pl)
diff --git a/current/doc/README.nls b/current/doc/README.nls
new file mode 100644
index 00000000..5a4ea285
--- /dev/null
+++ b/current/doc/README.nls
@@ -0,0 +1,30 @@
+I've added in password suite 980724 nls and locale support (currently
+only for greek). Before compiling (configuring) you must have set the
+environment variable LINGUAS=el for greek or LINGUAS="" just for english.
+To see your language at login (to the other programs export LANG=el is
+enough) when you enter your login add LANG=xx, where xx is your language.
+An other way to accomplish it is change the variable ENVIRON_FILE in
+/etc/login.defs from /etc/environment to .environment. Thus any user
+can add, to his .environment file, his language eg. LANG=el.
+
+Nikos Mavroyanopoulos
+ nmav@i-net.paiko.gr
+
+Note: i18n support as of this release (981218) can have some rough
+edges - because of the large number of files updated, there is always
+a possibility that I have introduced some new bugs. There are also
+potential security problems in GNU gettext (both the included one and
+one found in glibc 2.0.x) related to environment variables (LANG,
+LANGUAGE, LC_*, NLSPATH) when used in setuid programs. I have tried
+to work around them in sanitize_env() but no guarantees. The problem
+has been reported to the gettext maintainer.
+
+Also, you may not be able to legally distribute binaries compiled
+with included gettext (GPL and BSD-like licenses are not compatible).
+I believe that distribution in the same source archive is OK though
+(it's a "mere aggregation of another work not based on the Program
+with the Program" - here Program == gettext library - "on a volume of
+a storage or distribution medium"). Please tell the FSF politely that
+they should consider changing the gettext license to LGPL. Thanks!
+
+Marek
diff --git a/current/doc/README.pam b/current/doc/README.pam
new file mode 100644
index 00000000..4a873640
--- /dev/null
+++ b/current/doc/README.pam
@@ -0,0 +1,35 @@
+
+About PAM support in the Shadow Password Suite
+
+Warning: this code is still considered BETA. It needs more testing.
+Please let me know if it works, or if something doesn't work.
+
+Use "./configure --with-libpam" to enable PAM support in the login,
+passwd and su applications.
+
+When compiled with PAM support enabled, the following traditional features
+of the shadow suite are not implemented directly in the applications -
+instead, they should be implemented in the PAM modules.
+
+login:
+ - /etc/login.access
+ - /etc/porttime
+ - resource limits
+ - console groups
+ - password expiration / password strength checks
+ - /etc/motd and mail check
+
+passwd:
+ - administrator defined authentication methods
+ - TCFS support
+ - password expiration
+ - password strength checks
+
+su:
+ - wheel group
+ - console groups
+ - su access control (/etc/suauth)
+ - password expiration
+ - time restrictions
+ - resource limits
+
diff --git a/current/doc/README.platforms b/current/doc/README.platforms
new file mode 100644
index 00000000..a475af9e
--- /dev/null
+++ b/current/doc/README.platforms
@@ -0,0 +1,33 @@
+# $Id: README.platforms,v 1.4 1999/06/07 16:40:44 marekm Exp $
+#
+# This is the current (still incomplete) list of platforms this
+# package has been verified to work on. Additions (preferably
+# in the format as described below) are welcome. Thanks!
+#
+# V: last version reported to work
+# H: host type
+# L: Linux libc version
+# D: Linux distribution, or other OS name and version
+# C: changes (if any)
+# R: reported by
+
+V: 980529
+H: sparc-unknown-linux-gnu
+L: glibc-2.0.7
+D: Ultrapenguin-1.0.9
+C: had to explicitly disable desrpc.
+R: Bjorn Christianson <bjorn@cascade.psychology.mcmaster.ca>
+
+V: 980724
+H: i486-pc-linux-gnulibc1
+L: libc-5.4.33
+D: Debian-1.3.1.r6
+C: none (use dpkg-buildpackage)
+R: Marek Michalkiewicz <marekm@linux.org.pl>
+
+V: current
+H: i686-pc-linux-gnu
+L: glibc-2.0.7.19981211
+D: Debian-2.1
+C: none (use dpkg-buildpackage)
+R: Marek Michalkiewicz <marekm@linux.org.pl>
diff --git a/current/doc/README.shadow-paper b/current/doc/README.shadow-paper
new file mode 100644
index 00000000..bf4a83b2
--- /dev/null
+++ b/current/doc/README.shadow-paper
@@ -0,0 +1,25 @@
+Date: Fri, 06 Jun 1997 22:57:27 -0500
+From: Julie Haugh <jfh@tab.com>
+To: marekm@piast.t19.ds.pwr.wroc.pl
+CC: shadow-list@neptune.cin.net, debian-devel@lists.debian.org
+Subject: Shadow Paper available from the web now.
+
+Greets,
+
+I've finally managed to key in my '92 security paper on Shadow. You can
+find it at
+
+ http://www.tab.com/~jfh/shadow-paper.html
+
+As I get some time to go over how things have changed in the last 5
+years I intend to update it.
+
+My next Shadow-related project is cleaning up the documentation I
+started for the Trusted Subsystem evaluation I started a couple of
+years ago. There are a few really worthwhile documents a system
+administrator might enjoy in there.
+--
+Julianne Frances Haugh Feminism:
+mailto:jfh@tab.com The belief (considered radical by
+http://www.tab.com/~jfh some) that women are people, too.
+
diff --git a/current/doc/README.sun4 b/current/doc/README.sun4
new file mode 100644
index 00000000..8c3f037e
--- /dev/null
+++ b/current/doc/README.sun4
@@ -0,0 +1,39 @@
+[ $Id: README.sun4,v 1.1.1.1 1996/08/10 07:59:52 marekm Exp $ ]
+
+You'll need to do the following to get the shadow password dist to
+compile on a sun 4.1.1 system.
+
+copy Makefile.sun4 to Makefile, and make any system specific changes.
+
+copy config.h.sun4 config.h, and make any system specific changes.
+
+You may have to edit the pwd.h.m4 file by hand, as the sunos m4 may
+not grok the pwd.h.m4 file corectly. If you have the /usr/5bin/m4,
+substitute that. Be sure to delete the pwd.h file before typeing
+'make' again, as there will be an empty one left from the failed attempt
+to use the standard sunos m4.
+
+type 'make'. If everything goes well, then type 'make install'
+
+If using csh, then type 'rehash'. cd to the /etc directory and type
+'pwconv'. This will create two files, nshadow and npasswd.
+now type 'mkpasswd -f nshadow' and 'mkpasswd -f npasswd'. This will
+create the shadow password file.
+
+Note: The shadow group stuff does not work with sunos.
+
+Note: ftp will still use the old password file.
+
+Note: if you run suns pcnfs, be aware that it will still be looking at the
+ old password file as well. I may work out a patch for this, as I am
+ fairly certain the stuff on the sun side comes with source.
+
+Note: I have compiled this package with the standard c compiler and
+ suns unbundled c compiler at an optomization level of 2 in
+ both casses. Haven't tried gcc yet, so I don't know wether it
+ works. Same goes for suns C++ compiler.
+
+Note: has been compiled on a sun 3/75 running sunos 4.1.1. Should compile
+ fine on sun 4's running 4.1.1, and may compile on suns running
+ 4.1. Have no idea what sort of success people will have that
+ are running 4.03 and older versions.
diff --git a/current/doc/WISHLIST b/current/doc/WISHLIST
new file mode 100644
index 00000000..8ae49d50
--- /dev/null
+++ b/current/doc/WISHLIST
@@ -0,0 +1,53 @@
+$Id: WISHLIST,v 1.24 2000/08/26 18:27:09 marekm Exp $
+
+This is my wishlist for the shadow suite, in no particular order. Feel
+free to do anything from this list and mail me the diffs :-).
+
+Patches in diff -u format, against the latest version (sometimes in the
+"beta" directory) are preferred and make my job easier. Please, no
+MIME, base64, quoted-printable, or HTML. For very big patches, or if
+your mailer can corrupt them, please use gzip and uuencode. Thanks!
+
+New ideas to add to this list are welcome, too. --marekm
+
+- fix all the bugs, of course
+- implement "su only" accounts (no logins, only su from other account)
+- rewrite getdef.c to be more general? (no hardcoded names)
+- update man pages to reflect all the changes (real programmers ... :-)
+- patch for rlogind/telnetd to create utmp entry and fill in ut_addr
+- fix the usermod -l bug properly [for now it's OK - #undef AUTH_METHODS]
+- option to specify encrypted password in passwd (for yppasswdd, so it
+ doesn't need to know about shadow/non-shadow); should probably use a pipe
+ (less insecure than command line arguments)
+- add support for changing NIS passwords
+- clean up NDBM support, do it in the library and not in all programs
+- add option to check passwords by piping them to external programs
+- add functionality of the contrib/rpasswd.c wrapper to passwd
+- option to generate pronounceable passwords (like on SCO), external program?
+- poppassd (remote password change for eudora etc.)
+- add support for passwd/shadow db files (glibc)
+- better documentation
+- su -l, -m, -p, -s options (as in GNU su) - done in the Debian patches
+- vipw: check password files for errors after editing
+- clean up login utmp(x) handling code
+- add "maximum time users allowed to stay logged in" limit option to logoutd
+- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
+- write man pages: dialups.5, d_passwd.5
+- better utmpx support (logoutd, ...)
+- better OPIE support (report number of logins left, etc.)
+- new option for /etc/suauth: don't load user's environment (force "su -")
+ suggested by Ulisses Alonso Camaro
+- clean up error messages - "program_name: text of error message\n"
+ (maybe some common code for common messages about failing to lock/open
+ something)
+- find out why recent releases won't compile on Solaris
+- newusers UID/GID selection algorithm should be the same as useradd
+ (and use UID_MIN, UID_MAX from login.defs)
+- newusers should be able to copy /etc/skel to the new home directory
+ (like useradd)
+- integrate the changes from Debian (complete PAM support, bug fixes)
+- add directories where other packages can add hooks for package-specific
+ per-user configuration, to be executed with run-parts. Some hooks should
+ be executed at package install time for existing users, likewise for
+ package removal and possibly modification. (Debian Bug#36019)
+
diff --git a/current/doc/console.c.spec.txt b/current/doc/console.c.spec.txt
new file mode 100644
index 00000000..27830e7f
--- /dev/null
+++ b/current/doc/console.c.spec.txt
@@ -0,0 +1,36 @@
+$Id: console.c.spec.txt,v 1.1 1997/06/16 00:02:41 marekm Exp $
+
+Specification for console.c source file --
+
+input values --
+ tty -- character pointer to device name with leading "/dev/"
+ removed.
+
+return values --
+ 0 -- false
+ 1 -- true
+
+int console (char * tty)
+ if "CONSOLE" string value is not present in login.defs
+ return true
+
+ if the first character of "CONSOLE" string value is not "/"
+ treat the string as a ":" delimited list of device
+ names and search for the value of tty in that
+ tokenized list.
+
+ if a match is found
+ return true
+
+ return false
+
+ if the file named by "CONSOLE" cannot be opened
+ return true
+
+ scan the file looking for a match between the input line
+ and the value of tty
+
+ if a match is found
+ return true
+
+ return false
diff --git a/current/doc/cracklib26.diff b/current/doc/cracklib26.diff
new file mode 100644
index 00000000..09160b8c
--- /dev/null
+++ b/current/doc/cracklib26.diff
@@ -0,0 +1,340 @@
+diff -ur orig/cracklib26_small/cracklib/fascist.c cracklib26_small/cracklib/fascist.c
+--- orig/cracklib26_small/cracklib/fascist.c Mon Dec 15 02:56:55 1997
++++ cracklib26_small/cracklib/fascist.c Sat Apr 4 22:14:45 1998
+@@ -12,6 +12,7 @@
+ #include <ctype.h>
+ #include <sys/types.h>
+ #include <pwd.h>
++#include <string.h>
+
+ #define ISSKIP(x) (isspace(x) || ispunct(x))
+
+@@ -460,28 +461,27 @@
+ }
+
+ char *
+-FascistGecos(password, uid)
++FascistGecosPw(password, pwd)
+ char *password;
+- int uid;
++ struct passwd *pwd;
+ {
+ int i;
+ int j;
+ int wc;
+ char *ptr;
+- struct passwd *pwp;
+ char gbuffer[STRINGSIZE];
+ char tbuffer[STRINGSIZE];
+ char *uwords[STRINGSIZE];
+ char longbuffer[STRINGSIZE * 2];
+
+- if (!(pwp = getpwuid(uid)))
++ if (!pwd)
+ {
+ return ("you are not registered in the password file");
+ }
+
+ /* lets get really paranoid and assume a dangerously long gecos entry */
+
+- strncpy(tbuffer, pwp->pw_name, STRINGSIZE);
++ strncpy(tbuffer, pwd->pw_name, STRINGSIZE);
+ tbuffer[STRINGSIZE-1] = '\0';
+ if (GTry(tbuffer, password))
+ {
+@@ -490,12 +490,13 @@
+
+ /* it never used to be that you got passwd strings > 1024 chars, but now... */
+
+- strncpy(tbuffer, pwp->pw_gecos, STRINGSIZE);
++ strncpy(tbuffer, pwd->pw_gecos, STRINGSIZE);
+ tbuffer[STRINGSIZE-1] = '\0';
+ strcpy(gbuffer, Lowercase(tbuffer));
+
+ wc = 0;
+ ptr = gbuffer;
++ uwords[0] = (char *) 0;
+
+ while (*ptr)
+ {
+@@ -530,6 +531,8 @@
+ *(ptr++) = '\0';
+ }
+ }
++ if (!uwords[0])
++ return ((char *) 0); /* empty gecos */
+ #ifdef DEBUG
+ for (i = 0; uwords[i]; i++)
+ {
+@@ -586,9 +589,10 @@
+ }
+
+ char *
+-FascistLook(pwp, instring)
++FascistLookPw(pwp, instring, pwd)
+ PWDICT *pwp;
+ char *instring;
++ struct passwd *pwd;
+ {
+ int i;
+ char *ptr;
+@@ -667,7 +671,7 @@
+ return ("it looks like a National Insurance number.");
+ }
+
+- if (ptr = FascistGecos(password, getuid()))
++ if (ptr = FascistGecosPw(password, pwd ? pwd : getpwuid(getuid())))
+ {
+ return (ptr);
+ }
+@@ -715,9 +719,10 @@
+ }
+
+ char *
+-FascistCheck(password, path)
++FascistCheckPw(password, path, pwd)
+ char *password;
+ char *path;
++ struct passwd *pwd;
+ {
+ static char lastpath[STRINGSIZE];
+ static PWDICT *pwp;
+@@ -750,5 +755,29 @@
+ strncpy(lastpath, path, STRINGSIZE);
+ }
+
+- return (FascistLook(pwp, pwtrunced));
++ return (FascistLookPw(pwp, pwtrunced, pwd));
++}
++
++char *
++FascistGecos(password, uid)
++ char *password;
++ int uid;
++{
++ return (FascistGecosPw(password, getpwuid(uid)));
++}
++
++char *
++FascistLook(pwp, instring)
++ PWDICT *pwp;
++ char *instring;
++{
++ return (FascistLookPw(pwp, instring, (char *) 0));
++}
++
++char *
++FascistCheck(password, path)
++ char *password;
++ char *path;
++{
++ return (FascistCheckPw(password, path, (char *) 0));
+ }
+diff -ur orig/cracklib26_small/cracklib/packer.h cracklib26_small/cracklib/packer.h
+--- orig/cracklib26_small/cracklib/packer.h Mon Dec 15 00:09:30 1997
++++ cracklib26_small/cracklib/packer.h Sat Jan 10 22:13:46 1998
+@@ -34,6 +34,7 @@
+ FILE *dfp;
+ FILE *wfp;
+
++ int canfree;
+ int32 flags;
+ #define PFOR_WRITE 0x0001
+ #define PFOR_FLUSH 0x0002
+diff -ur orig/cracklib26_small/cracklib/packlib.c cracklib26_small/cracklib/packlib.c
+--- orig/cracklib26_small/cracklib/packlib.c Fri Jul 9 22:22:58 1993
++++ cracklib26_small/cracklib/packlib.c Sat Jan 10 22:28:49 1998
+@@ -16,7 +16,7 @@
+ char *mode;
+ {
+ int32 i;
+- static PWDICT pdesc;
++ PWDICT *pdesc;
+ char iname[STRINGSIZE];
+ char dname[STRINGSIZE];
+ char wname[STRINGSIZE];
+@@ -25,92 +25,94 @@
+ FILE *ifp;
+ FILE *wfp;
+
+- if (pdesc.header.pih_magic == PIH_MAGIC)
+- {
+- fprintf(stderr, "%s: another dictionary already open\n", prefix);
++ if ((pdesc = (PWDICT *) malloc(sizeof(PWDICT))) == 0)
+ return ((PWDICT *) 0);
+- }
+
+- memset(&pdesc, '\0', sizeof(pdesc));
++ memset(pdesc, '\0', sizeof(*pdesc));
+
+ sprintf(iname, "%s.pwi", prefix);
+ sprintf(dname, "%s.pwd", prefix);
+ sprintf(wname, "%s.hwm", prefix);
+
+- if (!(pdesc.dfp = fopen(dname, mode)))
++ if (!(pdesc->dfp = fopen(dname, mode)))
+ {
+ perror(dname);
++ free(pdesc);
+ return ((PWDICT *) 0);
+ }
+
+- if (!(pdesc.ifp = fopen(iname, mode)))
++ if (!(pdesc->ifp = fopen(iname, mode)))
+ {
+- fclose(pdesc.dfp);
++ fclose(pdesc->dfp);
+ perror(iname);
++ free(pdesc);
+ return ((PWDICT *) 0);
+ }
+
+- if (pdesc.wfp = fopen(wname, mode))
++ if (pdesc->wfp = fopen(wname, mode))
+ {
+- pdesc.flags |= PFOR_USEHWMS;
++ pdesc->flags |= PFOR_USEHWMS;
+ }
+
+- ifp = pdesc.ifp;
+- dfp = pdesc.dfp;
+- wfp = pdesc.wfp;
++ ifp = pdesc->ifp;
++ dfp = pdesc->dfp;
++ wfp = pdesc->wfp;
+
+ if (mode[0] == 'w')
+ {
+- pdesc.flags |= PFOR_WRITE;
+- pdesc.header.pih_magic = PIH_MAGIC;
+- pdesc.header.pih_blocklen = NUMWORDS;
+- pdesc.header.pih_numwords = 0;
++ pdesc->flags |= PFOR_WRITE;
++ pdesc->header.pih_magic = PIH_MAGIC;
++ pdesc->header.pih_blocklen = NUMWORDS;
++ pdesc->header.pih_numwords = 0;
+
+- fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
++ fwrite((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp);
+ } else
+ {
+- pdesc.flags &= ~PFOR_WRITE;
++ pdesc->flags &= ~PFOR_WRITE;
+
+- if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
++ if (!fread((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp))
+ {
+ fprintf(stderr, "%s: error reading header\n", prefix);
+
+- pdesc.header.pih_magic = 0;
++ pdesc->header.pih_magic = 0;
+ fclose(ifp);
+ fclose(dfp);
++ free(pdesc);
+ return ((PWDICT *) 0);
+ }
+
+- if (pdesc.header.pih_magic != PIH_MAGIC)
++ if (pdesc->header.pih_magic != PIH_MAGIC)
+ {
+ fprintf(stderr, "%s: magic mismatch\n", prefix);
+
+- pdesc.header.pih_magic = 0;
++ pdesc->header.pih_magic = 0;
+ fclose(ifp);
+ fclose(dfp);
++ free(pdesc);
+ return ((PWDICT *) 0);
+ }
+
+- if (pdesc.header.pih_blocklen != NUMWORDS)
++ if (pdesc->header.pih_blocklen != NUMWORDS)
+ {
+ fprintf(stderr, "%s: size mismatch\n", prefix);
+
+- pdesc.header.pih_magic = 0;
++ pdesc->header.pih_magic = 0;
+ fclose(ifp);
+ fclose(dfp);
++ free(pdesc);
+ return ((PWDICT *) 0);
+ }
+
+- if (pdesc.flags & PFOR_USEHWMS)
++ if (pdesc->flags & PFOR_USEHWMS)
+ {
+- if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
++ if (fread(pdesc->hwms, 1, sizeof(pdesc->hwms), wfp) != sizeof(pdesc->hwms))
+ {
+- pdesc.flags &= ~PFOR_USEHWMS;
++ pdesc->flags &= ~PFOR_USEHWMS;
+ }
+ }
+ }
+-
+- return (&pdesc);
++ pdesc->canfree = 1;
++ return (pdesc);
+ }
+
+ int
+@@ -159,8 +161,13 @@
+
+ fclose(pwp->ifp);
+ fclose(pwp->dfp);
++ if (pwp->wfp)
++ fclose(pwp->wfp);
+
+- pwp->header.pih_magic = 0;
++ if (pwp->canfree)
++ free(pwp);
++ else
++ pwp->header.pih_magic = 0;
+
+ return (0);
+ }
+@@ -307,6 +314,11 @@
+ register char *this;
+ int idx;
+
++/*
++ * comment in npasswd-2.0beta4 says this:
++ * This does not work under all circumstances, so don't bother
++ */
++#if 0
+ if (pwp->flags & PFOR_USEHWMS)
+ {
+ idx = string[0] & 0xff;
+@@ -317,6 +329,10 @@
+ lwm = 0;
+ hwm = PW_WORDS(pwp) - 1;
+ }
++#else
++ lwm = 0;
++ hwm = PW_WORDS(pwp);
++#endif
+
+ #ifdef DEBUG
+ printf("---- %lu, %lu ----\n", lwm, hwm);
+diff -ur orig/cracklib26_small/util/mkdict cracklib26_small/util/mkdict
+--- orig/cracklib26_small/util/mkdict Fri Jul 9 22:23:03 1993
++++ cracklib26_small/util/mkdict Sat Apr 4 22:31:45 1998
+@@ -14,9 +14,16 @@
+ SORT="sort"
+ ###SORT="sort -T /tmp"
+
+-cat $* |
++### Use zcat to read compressed (as well as uncompressed) dictionaries.
++### Compressed dictionaries can save quite a lot of disk space.
++
++CAT="gzip -cdf"
++###CAT="zcat"
++###CAT="cat"
++
++$CAT $* |
+ tr '[A-Z]' '[a-z]' |
+- tr -cd '[\012a-z0-9]' |
++ tr -cd '\012[a-z][0-9]' |
+ $SORT |
+ uniq |
+ grep -v '^#' |
diff --git a/current/etc/Makefile.am b/current/etc/Makefile.am
new file mode 100644
index 00000000..f2ce1621
--- /dev/null
+++ b/current/etc/Makefile.am
@@ -0,0 +1,7 @@
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+EXTRA_DIST = limits login.access login.defs login.defs.hurd login.defs.linux \
+ shells suauth
+
+SUBDIRS = pam.d
diff --git a/current/etc/Makefile.in b/current/etc/Makefile.in
new file mode 100644
index 00000000..c27dab48
--- /dev/null
+++ b/current/etc/Makefile.in
@@ -0,0 +1,318 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+EXTRA_DIST = limits login.access login.defs login.defs.hurd login.defs.linux shells suauth
+
+
+SUBDIRS = pam.d
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps etc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = etc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/etc/limits b/current/etc/limits
new file mode 100644
index 00000000..fc741b1a
--- /dev/null
+++ b/current/etc/limits
@@ -0,0 +1,28 @@
+# /etc/limits contains user resource limits.
+# See limits(5).
+#
+# Format:
+# <username> <limits-string>
+#
+# default entry is '*' for username
+#
+# Valid flags are:
+# A: max address space (KB)
+# C: max core file size (KB)
+# D: max data size (KB)
+# F: maximum filesize (KB)
+# M: max locked-in-memory address space (KB) [only for root on Linux 2.0.x]
+# N: max number of open files
+# R: max resident set size (KB) [no effect on Linux 2.0.x]
+# S: max stack size (KB)
+# T: max CPU time (MIN)
+# U: max number of processes
+# L: max number of logins for this user
+#
+# Examples:
+# the default entry
+#* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0
+# another way of suspending a user login
+#guest L0
+# this account has no limits
+#sysadm -
diff --git a/current/etc/login.access b/current/etc/login.access
new file mode 100644
index 00000000..60cbd63f
--- /dev/null
+++ b/current/etc/login.access
@@ -0,0 +1,54 @@
+# $Id: login.access,v 1.2 1996/09/10 02:45:04 marekm Exp $
+#
+# Login access control table.
+#
+# When someone logs in, the table is scanned for the first entry that
+# matches the (user, host) combination, or, in case of non-networked
+# logins, the first entry that matches the (user, tty) combination. The
+# permissions field of that table entry determines whether the login will
+# be accepted or refused.
+#
+# Format of the login access control table is three fields separated by a
+# ":" character:
+#
+# permission : users : origins
+#
+# The first field should be a "+" (access granted) or "-" (access denied)
+# character.
+#
+# The second field should be a list of one or more login names, group
+# names, or ALL (always matches). A pattern of the form user@host is
+# matched when the login name matches the "user" part, and when the
+# "host" part matches the local machine name.
+#
+# The third field should be a list of one or more tty names (for
+# non-networked logins), host names, domain names (begin with "."), host
+# addresses, internet network numbers (end with "."), ALL (always
+# matches) or LOCAL (matches any string that does not contain a "."
+# character).
+#
+# If you run NIS you can use @netgroupname in host or user patterns; this
+# even works for @usergroup@@hostgroup patterns. Weird.
+#
+# The EXCEPT operator makes it possible to write very compact rules.
+#
+# The group file is searched only when a name does not match that of the
+# logged-in user. Only groups are matched in which users are explicitly
+# listed: the program does not look at a user's primary group id value.
+#
+##############################################################################
+#
+# Disallow console logins to all but a few accounts.
+#
+#-:ALL EXCEPT wheel shutdown sync:console
+#
+# Disallow non-local logins to privileged accounts (group wheel).
+#
+#-:wheel:ALL EXCEPT LOCAL .win.tue.nl
+#
+# Some accounts are not allowed to login from anywhere:
+#
+#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL
+#
+# All other accounts are allowed to login from anywhere.
+#
diff --git a/current/etc/login.defs b/current/etc/login.defs
new file mode 100644
index 00000000..7af8d118
--- /dev/null
+++ b/current/etc/login.defs
@@ -0,0 +1,214 @@
+#
+# /etc/login.defs - Configuration control definitions for the login package.
+#
+# $Id: login.defs,v 1.2 1997/05/01 23:14:35 marekm Exp $
+#
+# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH.
+# If unspecified, some arbitrary (and possibly incorrect) value will
+# be assumed. All other items are optional - if not specified then
+# the described action or option will be inhibited.
+#
+# Comment lines (lines beginning with "#") and blank lines are ignored.
+#
+
+#
+# Delay in seconds before being allowed another attempt after a login failure
+#
+FAIL_DELAY 5
+
+#
+# Enable additional passwords upon dialup lines specified in /etc/dialups.
+#
+DIALUPS_CHECK_ENAB yes
+
+#
+# Enable logging and display of /usr/adm/faillog login failure info.
+#
+FAILLOG_ENAB yes
+
+#
+# Enable display of unknown usernames when login failures are recorded.
+#
+LOG_UNKFAIL_ENAB yes
+
+#
+# Enable logging and display of /usr/adm/lastlog login time info.
+#
+LASTLOG_ENAB yes
+
+#
+# Enable checking and display of mailbox status upon login.
+#
+MAIL_CHECK_ENAB yes
+
+#
+# Enable additional checks upon password changes.
+#
+OBSCURE_CHECKS_ENAB yes
+
+#
+# Enable checking of time restrictions specified in /etc/porttime.
+#
+PORTTIME_CHECKS_ENAB yes
+
+#
+# Enable setting of ulimit, umask, and niceness from passwd gecos field.
+#
+QUOTAS_ENAB yes
+
+#
+# Enable "syslog" logging of su activity - in addition to sulog file logging.
+# SYSLOG_SG_ENAB does the same for newgrp and sg.
+#
+SYSLOG_SU_ENAB no
+SYSLOG_SG_ENAB no
+
+#
+# If defined, either full pathname of a file containing device names or
+# a ":" delimited list of device names. Root logins will be allowed only
+# upon these devices.
+#
+CONSOLE /etc/consoles
+#CONSOLE console:tty01:tty02:tty03:tty04
+
+#
+# If defined, all su activity is logged to this file.
+#
+SULOG_FILE /usr/adm/sulog
+
+#
+# If defined, ":" delimited list of "message of the day" files to
+# be displayed upon login.
+#
+MOTD_FILE /etc/motd
+#MOTD_FILE /etc/motd:/usr/lib/news/news-motd
+
+#
+# If defined, this file will be output before each login prompt.
+#
+#ISSUE_FILE /etc/issue
+
+#
+# If defined, file which maps tty line to TERM environment parameter.
+# Each line of the file is in a format something like "vt100 tty01".
+#
+TTYTYPE_FILE /etc/ttytype
+
+#
+# If defined, login failures will be logged here in a utmp format.
+#
+FTMP_FILE /etc/ftmp
+
+#
+# If defined, name of file whose presence which will inhibit non-root
+# logins. The contents of this file should be a message indicating
+# why logins are inhibited.
+#
+NOLOGINS_FILE /etc/nologins
+
+#
+# If defined, the command name to display when running "su -". For
+# example, if this is defined as "su" then a "ps" will display the
+# command is "-su". If not defined, then "ps" would display the
+# name of the shell actually being run, e.g. something like "-sh".
+#
+SU_NAME su
+
+#
+# *REQUIRED*
+# Directory where mailboxes reside, _or_ name of file, relative to the
+# home directory. If you _do_ define both, MAIL_DIR takes precedence.
+# MAILDIR is for Qmail
+#
+#MAILDIR Maildir
+MAIL_DIR /usr/spool/mail
+#MAIL_FILE .mail
+
+#
+# If defined, file which inhibits all the usual chatter during the login
+# sequence. If a full pathname, then hushed mode will be enabled if the
+# user's name or shell are found in the file. If not a full pathname, then
+# hushed mode will be enabled if the file exists in the user's home directory.
+#
+#HUSHLOGIN_FILE .hushlogin
+HUSHLOGIN_FILE /etc/hushlogins
+
+#
+# If defined, the presence of this value in an /etc/passwd "shell" field will
+# disable logins for that user, although "su" will still be allowed.
+#
+NOLOGIN_STR NOLOGIN
+
+#
+# If defined, either a TZ environment parameter spec or the
+# fully-rooted pathname of a file containing such a spec.
+#
+ENV_TZ TZ=CST6CDT
+#ENV_TZ /etc/tzname
+
+#
+# If defined, an HZ environment parameter spec.
+#
+ENV_HZ HZ=50
+
+#
+# *REQUIRED* The default PATH settings, for superuser and normal users.
+#
+ENV_SUPATH PATH=/etc/local:/etc:/local/bin:/usr/bin:/bin
+ENV_PATH PATH=/local/bin:/usr/bin:/bin
+
+#
+# Terminal permissions
+#
+# TTYGROUP Login tty will be assigned this group ownership.
+# TTYPERM Login tty will be set to this permission.
+#
+# If you have a "write" program which is "setgid" to a special group
+# which owns the terminals, define TTYGROUP to the group number and
+# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign
+# TTYPERM to either 622 or 600.
+#
+#TTYGROUP 7
+#TTYPERM 0620
+TTYPERM 0622
+
+#
+# Login configuration initializations:
+#
+# ERASECHAR Terminal ERASE character ('\010' = backspace).
+# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
+# UMASK Default "umask" value.
+# ULIMIT Default "ulimit" value.
+#
+# The ERASECHAR and KILLCHAR are used only on System V machines.
+# The ULIMIT is used only if the system supports it.
+#
+# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
+#
+ERASECHAR 010
+KILLCHAR 025
+UMASK 022
+ULIMIT 2097152
+
+#
+# Password aging controls:
+#
+# PASS_MAX_DAYS Maximum number of days a password may be used.
+# PASS_MIN_DAYS Minimum number of days allowed between password changes.
+# PASS_MIN_LEN Minimum acceptable password length.
+# PASS_WARN_AGE Number of days warning given before a password expires.
+#
+PASS_MAX_DAYS 99999
+PASS_MIN_DAYS 0
+PASS_MIN_LEN 5
+PASS_WARN_AGE 7
+
+#
+# Only allow group 0 members to "su" to root.
+#
+SU_WHEEL_ONLY no
+
+#
+# If compiled with cracklib support, where are the dictionaries
+#
+#CRACKLIB_DICTPATH /usr/share/lib/pw_dict
diff --git a/current/etc/login.defs.hurd b/current/etc/login.defs.hurd
new file mode 100644
index 00000000..e7cdb4df
--- /dev/null
+++ b/current/etc/login.defs.hurd
@@ -0,0 +1,143 @@
+#
+# /etc/login.defs - Configuration control definitions for the login package.
+#
+# $Id: login.defs.hurd,v 1.2 2000/08/26 18:27:10 marekm Exp $
+#
+# One item must be defined: MAIL_DIR.
+# If unspecified, some arbitrary (and possibly incorrect) value will
+# be assumed. All other items are optional - if not specified then
+# the described action or option will be inhibited.
+#
+# Comment lines (lines beginning with "#") and blank lines are ignored.
+#
+# Modified for the Hurd. --brinkmd
+
+#
+# Enable additional checks upon password changes.
+#
+OBSCURE_CHECKS_ENAB yes
+
+#
+# *REQUIRED*
+# Directory where mailboxes reside, _or_ name of file, relative to the
+# home directory. If you _do_ define both, MAIL_DIR takes precedence.
+# QMAIL_DIR is for Qmail
+#
+#QMAIL_DIR Maildir
+MAIL_DIR /var/spool/mail
+#MAIL_FILE .mail
+
+#
+# Password aging controls:
+#
+# PASS_MAX_DAYS Maximum number of days a password may be used.
+# PASS_MIN_DAYS Minimum number of days allowed between password changes.
+# PASS_MIN_LEN Minimum acceptable password length.
+# PASS_WARN_AGE Number of days warning given before a password expires.
+#
+PASS_MAX_DAYS 99999
+PASS_MIN_DAYS 0
+PASS_MIN_LEN 5
+PASS_WARN_AGE 7
+
+#
+# If compiled with cracklib support, where are the dictionaries
+#
+#CRACKLIB_DICTPATH /usr/lib/passwd/pw_dict
+
+#
+# Min/max values for automatic uid selection in useradd
+#
+UID_MIN 1000
+UID_MAX 60000
+
+#
+# Min/max values for automatic gid selection in groupadd
+#
+GID_MIN 100
+GID_MAX 60000
+
+#
+# Maximum number of attempts to change password if rejected (too easy)
+#
+PASS_CHANGE_TRIES 5
+
+#
+# Warn about weak passwords (but still allow them) if you are root.
+#
+PASS_ALWAYS_WARN yes
+
+#
+# Number of significant characters in the password for crypt().
+# Default is 8, don't change unless your crypt() is better.
+# Ignored if MD5_CRYPT_ENAB set to "yes".
+#
+#PASS_MAX_LEN 8
+
+#
+# Require password before chfn/chsh can make any changes.
+#
+CHFN_AUTH yes
+
+#
+# Which fields may be changed by regular users using chfn - use
+# any combination of letters "frwh" (full name, room number, work
+# phone, home phone). If not defined, no changes are allowed.
+# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
+#
+CHFN_RESTRICT rwh
+
+#
+# Password prompt (%s will be replaced by user name).
+#
+# XXX - it doesn't work correctly yet, for now leave it commented out
+# to use the default which is just "Password: ".
+#LOGIN_STRING "%s's Password: "
+
+#
+# Only works if compiled with MD5_CRYPT defined:
+# If set to "yes", new passwords will be encrypted using the MD5-based
+# algorithm compatible with the one used by recent releases of FreeBSD.
+# It supports passwords of unlimited length and longer salt strings.
+# Set to "no" if you need to copy encrypted passwords to other systems
+# which don't understand the new algorithm. Default is "no".
+#
+#MD5_CRYPT_ENAB no
+
+#
+# If defined, this command is run when removing a user.
+# It should remove any at/cron/print jobs etc. owned by
+# the user to be removed (passed as the first argument).
+#
+#USERDEL_CMD /usr/sbin/userdel_local
+
+#
+# When prompting for password without echo, getpass() can optionally
+# display a random number (in the range 1 to GETPASS_ASTERISKS) of '*'
+# characters for each character typed. This feature is designed to
+# confuse people looking over your shoulder when you enter a password :-).
+# Also, the new getpass() accepts both Backspace (8) and Delete (127)
+# keys to delete previous character (to cope with different terminal
+# types), Control-U to delete all characters, and beeps when there are
+# no more characters to delete, or too many characters entered.
+#
+# Setting GETPASS_ASTERISKS to 1 results in more traditional behaviour -
+# exactly one '*' displayed for each character typed.
+#
+# Setting GETPASS_ASTERISKS to 0 disables the '*' characters (Backspace,
+# Delete, Control-U and beep continue to work as described above).
+#
+# Setting GETPASS_ASTERISKS to -1 reverts to the traditional getpass()
+# without any new features. This is the default.
+#
+#GETPASS_ASTERISKS 1
+
+#
+# Enable setting of the umask group bits to be the same as owner bits
+# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
+# the same as gid, and username is the same as the primary group name.
+#
+# This also enables userdel to remove user groups if no members exist.
+#
+USERGROUPS_ENAB yes
+
diff --git a/current/etc/login.defs.linux b/current/etc/login.defs.linux
new file mode 100644
index 00000000..94402934
--- /dev/null
+++ b/current/etc/login.defs.linux
@@ -0,0 +1,370 @@
+#
+# /etc/login.defs - Configuration control definitions for the login package.
+#
+# $Id: login.defs.linux,v 1.12 2000/08/26 18:27:10 marekm Exp $
+#
+# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH.
+# If unspecified, some arbitrary (and possibly incorrect) value will
+# be assumed. All other items are optional - if not specified then
+# the described action or option will be inhibited.
+#
+# Comment lines (lines beginning with "#") and blank lines are ignored.
+#
+# Modified for Linux. --marekm
+
+#
+# Delay in seconds before being allowed another attempt after a login failure
+#
+FAIL_DELAY 3
+
+#
+# Enable additional passwords upon dialup lines specified in /etc/dialups.
+#
+DIALUPS_CHECK_ENAB yes
+
+#
+# Enable logging and display of /var/log/faillog login failure info.
+#
+FAILLOG_ENAB yes
+
+#
+# Enable display of unknown usernames when login failures are recorded.
+#
+LOG_UNKFAIL_ENAB no
+
+#
+# Enable logging of successful logins
+#
+LOG_OK_LOGINS no
+
+#
+# Enable logging and display of /var/log/lastlog login time info.
+#
+LASTLOG_ENAB yes
+
+#
+# Enable checking and display of mailbox status upon login.
+#
+# Disable if the shell startup files already check for mail
+# ("mailx -e" or equivalent).
+#
+MAIL_CHECK_ENAB yes
+
+#
+# Enable additional checks upon password changes.
+#
+OBSCURE_CHECKS_ENAB yes
+
+#
+# Enable checking of time restrictions specified in /etc/porttime.
+#
+PORTTIME_CHECKS_ENAB yes
+
+#
+# Enable setting of ulimit, umask, and niceness from passwd gecos field.
+#
+QUOTAS_ENAB yes
+
+#
+# Enable "syslog" logging of su activity - in addition to sulog file logging.
+# SYSLOG_SG_ENAB does the same for newgrp and sg.
+#
+SYSLOG_SU_ENAB yes
+SYSLOG_SG_ENAB yes
+
+#
+# If defined, either full pathname of a file containing device names or
+# a ":" delimited list of device names. Root logins will be allowed only
+# upon these devices.
+#
+CONSOLE /etc/securetty
+#CONSOLE console:tty01:tty02:tty03:tty04
+
+#
+# If defined, all su activity is logged to this file.
+#
+#SULOG_FILE /var/log/sulog
+
+#
+# If defined, ":" delimited list of "message of the day" files to
+# be displayed upon login.
+#
+MOTD_FILE /etc/motd
+#MOTD_FILE /etc/motd:/usr/lib/news/news-motd
+
+#
+# If defined, this file will be output before each login prompt.
+#
+#ISSUE_FILE /etc/issue
+
+#
+# If defined, file which maps tty line to TERM environment parameter.
+# Each line of the file is in a format something like "vt100 tty01".
+#
+#TTYTYPE_FILE /etc/ttytype
+
+#
+# If defined, login failures will be logged here in a utmp format.
+# last, when invoked as lastb, will read /var/log/btmp, so...
+#
+FTMP_FILE /var/log/btmp
+
+#
+# If defined, name of file whose presence which will inhibit non-root
+# logins. The contents of this file should be a message indicating
+# why logins are inhibited.
+#
+NOLOGINS_FILE /etc/nologin
+
+#
+# If defined, the command name to display when running "su -". For
+# example, if this is defined as "su" then a "ps" will display the
+# command is "-su". If not defined, then "ps" would display the
+# name of the shell actually being run, e.g. something like "-sh".
+#
+SU_NAME su
+
+#
+# *REQUIRED*
+# Directory where mailboxes reside, _or_ name of file, relative to the
+# home directory. If you _do_ define both, MAIL_DIR takes precedence.
+# QMAIL_DIR is for Qmail
+#
+#QMAIL_DIR Maildir
+MAIL_DIR /var/spool/mail
+#MAIL_FILE .mail
+
+#
+# If defined, file which inhibits all the usual chatter during the login
+# sequence. If a full pathname, then hushed mode will be enabled if the
+# user's name or shell are found in the file. If not a full pathname, then
+# hushed mode will be enabled if the file exists in the user's home directory.
+#
+HUSHLOGIN_FILE .hushlogin
+#HUSHLOGIN_FILE /etc/hushlogins
+
+#
+# If defined, the presence of this value in an /etc/passwd "shell" field will
+# disable logins for that user, although "su" will still be allowed.
+#
+# XXX this does not seem to be implemented yet... --marekm
+# no, it was implemented but I ripped it out ;-) -- jfh
+NOLOGIN_STR NOLOGIN
+
+#
+# If defined, either a TZ environment parameter spec or the
+# fully-rooted pathname of a file containing such a spec.
+#
+#ENV_TZ TZ=CST6CDT
+#ENV_TZ /etc/tzname
+
+#
+# If defined, an HZ environment parameter spec.
+#
+# for Linux/x86
+ENV_HZ HZ=100
+# For Linux/Alpha...
+#ENV_HZ HZ=1024
+
+#
+# *REQUIRED* The default PATH settings, for superuser and normal users.
+#
+# (they are minimal, add the rest in the shell startup files)
+ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin
+ENV_PATH PATH=/bin:/usr/bin
+
+#
+# Terminal permissions
+#
+# TTYGROUP Login tty will be assigned this group ownership.
+# TTYPERM Login tty will be set to this permission.
+#
+# If you have a "write" program which is "setgid" to a special group
+# which owns the terminals, define TTYGROUP to the group number and
+# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign
+# TTYPERM to either 622 or 600.
+#
+TTYGROUP tty
+TTYPERM 0600
+
+#
+# Login configuration initializations:
+#
+# ERASECHAR Terminal ERASE character ('\010' = backspace).
+# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
+# UMASK Default "umask" value.
+# ULIMIT Default "ulimit" value.
+#
+# The ERASECHAR and KILLCHAR are used only on System V machines.
+# The ULIMIT is used only if the system supports it.
+# (now it works with setrlimit too; ulimit is in 512-byte units)
+#
+# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
+#
+ERASECHAR 0177
+KILLCHAR 025
+UMASK 022
+#ULIMIT 2097152
+
+#
+# Password aging controls:
+#
+# PASS_MAX_DAYS Maximum number of days a password may be used.
+# PASS_MIN_DAYS Minimum number of days allowed between password changes.
+# PASS_MIN_LEN Minimum acceptable password length.
+# PASS_WARN_AGE Number of days warning given before a password expires.
+#
+PASS_MAX_DAYS 99999
+PASS_MIN_DAYS 0
+PASS_MIN_LEN 5
+PASS_WARN_AGE 7
+
+#
+# If "yes", the user must be listed as a member of the first gid 0 group
+# in /etc/group (called "root" on most Linux systems) to be able to "su"
+# to uid 0 accounts. If the group doesn't exist or is empty, no one
+# will be able to "su" to uid 0.
+#
+SU_WHEEL_ONLY no
+
+#
+# If compiled with cracklib support, where are the dictionaries
+#
+CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict
+
+#
+# Min/max values for automatic uid selection in useradd
+#
+UID_MIN 1000
+UID_MAX 60000
+
+#
+# Min/max values for automatic gid selection in groupadd
+#
+GID_MIN 100
+GID_MAX 60000
+
+#
+# Max number of login retries if password is bad
+#
+LOGIN_RETRIES 5
+
+#
+# Max time in seconds for login
+#
+LOGIN_TIMEOUT 60
+
+#
+# Maximum number of attempts to change password if rejected (too easy)
+#
+PASS_CHANGE_TRIES 5
+
+#
+# Warn about weak passwords (but still allow them) if you are root.
+#
+PASS_ALWAYS_WARN yes
+
+#
+# Number of significant characters in the password for crypt().
+# Default is 8, don't change unless your crypt() is better.
+# Ignored if MD5_CRYPT_ENAB set to "yes".
+#
+#PASS_MAX_LEN 8
+
+#
+# Require password before chfn/chsh can make any changes.
+#
+CHFN_AUTH yes
+
+#
+# Which fields may be changed by regular users using chfn - use
+# any combination of letters "frwh" (full name, room number, work
+# phone, home phone). If not defined, no changes are allowed.
+# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
+#
+CHFN_RESTRICT rwh
+
+#
+# Password prompt (%s will be replaced by user name).
+#
+# XXX - it doesn't work correctly yet, for now leave it commented out
+# to use the default which is just "Password: ".
+#LOGIN_STRING "%s's Password: "
+
+#
+# Only works if compiled with MD5_CRYPT defined:
+# If set to "yes", new passwords will be encrypted using the MD5-based
+# algorithm compatible with the one used by recent releases of FreeBSD.
+# It supports passwords of unlimited length and longer salt strings.
+# Set to "no" if you need to copy encrypted passwords to other systems
+# which don't understand the new algorithm. Default is "no".
+#
+#MD5_CRYPT_ENAB no
+
+#
+# List of groups to add to the user's supplementary group set
+# when logging in on the console (as determined by the CONSOLE
+# setting). Default is none.
+#
+# Use with caution - it is possible for users to gain permanent
+# access to these groups, even when not logged in on the console.
+# How to do it is left as an exercise for the reader...
+#
+#CONSOLE_GROUPS floppy:audio:cdrom
+
+#
+# Should login be allowed if we can't cd to the home directory?
+# Default in no.
+#
+DEFAULT_HOME yes
+
+#
+# If this file exists and is readable, login environment will be
+# read from it. Every line should be in the form name=value.
+#
+ENVIRON_FILE /etc/environment
+
+#
+# If defined, this command is run when removing a user.
+# It should remove any at/cron/print jobs etc. owned by
+# the user to be removed (passed as the first argument).
+#
+#USERDEL_CMD /usr/sbin/userdel_local
+
+#
+# If defined, either full pathname of a file containing device names or
+# a ":" delimited list of device names. No password is required to log in
+# as a non-root user on these devices.
+#
+#NO_PASSWORD_CONSOLE tty1:tty2:tty3:tty4:tty5:tty6
+
+#
+# When prompting for password without echo, getpass() can optionally
+# display a random number (in the range 1 to GETPASS_ASTERISKS) of '*'
+# characters for each character typed. This feature is designed to
+# confuse people looking over your shoulder when you enter a password :-).
+# Also, the new getpass() accepts both Backspace (8) and Delete (127)
+# keys to delete previous character (to cope with different terminal
+# types), Control-U to delete all characters, and beeps when there are
+# no more characters to delete, or too many characters entered.
+#
+# Setting GETPASS_ASTERISKS to 1 results in more traditional behaviour -
+# exactly one '*' displayed for each character typed.
+#
+# Setting GETPASS_ASTERISKS to 0 disables the '*' characters (Backspace,
+# Delete, Control-U and beep continue to work as described above).
+#
+# Setting GETPASS_ASTERISKS to -1 reverts to the traditional getpass()
+# without any new features. This is the default.
+#
+#GETPASS_ASTERISKS 1
+
+#
+# Enable setting of the umask group bits to be the same as owner bits
+# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
+# the same as gid, and username is the same as the primary group name.
+#
+# This also enables userdel to remove user groups if no members exist.
+#
+USERGROUPS_ENAB yes
+
diff --git a/current/etc/pam.d/Makefile.am b/current/etc/pam.d/Makefile.am
new file mode 100644
index 00000000..c9041de6
--- /dev/null
+++ b/current/etc/pam.d/Makefile.am
@@ -0,0 +1,4 @@
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+EXTRA_DIST = passwd su
diff --git a/current/etc/pam.d/Makefile.in b/current/etc/pam.d/Makefile.in
new file mode 100644
index 00000000..83dbbb8b
--- /dev/null
+++ b/current/etc/pam.d/Makefile.in
@@ -0,0 +1,211 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+EXTRA_DIST = passwd su
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps etc/pam.d/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = etc/pam.d
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/etc/pam.d/passwd b/current/etc/pam.d/passwd
new file mode 100644
index 00000000..989d5b96
--- /dev/null
+++ b/current/etc/pam.d/passwd
@@ -0,0 +1,5 @@
+#%PAM-1.0
+#[For version 1.0 syntax, the above header is optional]
+# $Id: passwd,v 1.1 1998/07/23 22:13:15 marekm Exp $
+# /etc/pam.d/passwd - sample PAM config file for the `passwd' service
+password required pam_unix_passwd.so
diff --git a/current/etc/pam.d/su b/current/etc/pam.d/su
new file mode 100644
index 00000000..066be02e
--- /dev/null
+++ b/current/etc/pam.d/su
@@ -0,0 +1,7 @@
+#%PAM-1.0
+#[For version 1.0 syntax, the above header is optional]
+# $Id: su,v 1.1 1998/07/23 22:13:15 marekm Exp $
+# /etc/pam.d/su - sample PAM config file for the `su' service
+auth sufficient pam_rootok.so
+auth required pam_unix_auth.so
+account required pam_unix_acct.so
diff --git a/current/etc/shells b/current/etc/shells
new file mode 100644
index 00000000..e7f0e538
--- /dev/null
+++ b/current/etc/shells
@@ -0,0 +1,10 @@
+# /etc/shells: valid login shells
+/bin/ash
+/bin/bash
+/bin/csh
+/bin/sh
+/usr/bin/es
+/usr/bin/ksh
+/usr/bin/rc
+/usr/bin/tcsh
+/usr/bin/zsh
diff --git a/current/etc/suauth b/current/etc/suauth
new file mode 100644
index 00000000..85620c4f
--- /dev/null
+++ b/current/etc/suauth
@@ -0,0 +1,4 @@
+# /etc/suauth - secure-su control file. See suauth(5) for full documentation.
+
+# Uncommenting this line will only allow members of group root to su to root.
+# root:ALL EXCEPT GROUP root:DENY
diff --git a/current/install-sh b/current/install-sh
new file mode 100755
index 00000000..e9de2384
--- /dev/null
+++ b/current/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/current/intl/ChangeLog b/current/intl/ChangeLog
new file mode 100644
index 00000000..19895015
--- /dev/null
+++ b/current/intl/ChangeLog
@@ -0,0 +1,1086 @@
+1998-04-29 Ulrich Drepper <drepper@cygnus.com>
+
+ * intl/localealias.c (read_alias_file): Use unsigned char for
+ local variables. Remove unused variable tp.
+ * intl/l10nflist.c (_nl_normalize_codeset): Use unsigned char *
+ for type of codeset. For loosing Solaris systems.
+ * intl/loadinfo.h: Adapt prototype of _nl_normalize_codeset.
+ * intl/bindtextdom.c (BINDTEXTDOMAIN): Don't define local variable
+ len if not needed.
+ Patches by Jim Meyering.
+
+1998-04-28 Ulrich Drepper <drepper@cygnus.com>
+
+ * loadmsgcat.c (_nl_load_domain): Don't assign the element use_mmap if
+ mmap is not supported.
+
+ * hash-string.h: Don't include <values.h>.
+
+1998-04-27 Ulrich Drepper <drepper@cygnus.com>
+
+ * textdomain.c: Use strdup is available.
+
+ * localealias.c: Define HAVE_MEMPCPY so that we can use this
+ function. Define and use semapahores to protect modfication of
+ global objects when compiling for glibc. Add code to allow
+ freeing alias table.
+
+ * l10nflist.c: Don't assume stpcpy not being a macro.
+
+ * gettextP.h: Define internal_function macri if not already done.
+ Use glibc byte-swap macros instead of defining SWAP when compiled
+ for glibc.
+ (struct loaded_domain): Add elements to allow unloading.
+
+ * Makefile.in (distclean): Don't remove libintl.h here.
+
+ * bindtextdomain.c: Carry over changes from glibc. Use strdup if
+ available.
+
+ * dcgettext.c: Don't assume stpcpy not being a macro. Mark internal
+ functions. Add memory freeing code for glibc.
+
+ * dgettext.c: Update copyright.
+
+ * explodename.c: Include stdlib.h and string.h only if they exist.
+ Use strings.h eventually.
+
+ * finddomain.c: Mark internal functions. Use strdup if available.
+ Add memory freeing code for glibc.
+
+1997-10-10 20:00 Ulrich Drepper <drepper@cygnus.com>
+
+ * libgettext.h: Fix dummy textdomain and bindtextdomain macros.
+ They should return reasonable values.
+ Reported by Tom Tromey <tromey@cygnus.com>.
+
+1997-09-16 03:33 Ulrich Drepper <drepper@cygnus.com>
+
+ * libgettext.h: Define PARAMS also to `args' if __cplusplus is defined.
+ * intlh.inst.in: Likewise.
+ Reported by Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>.
+
+ * libintl.glibc: Update from current glibc version.
+
+1997-09-06 02:10 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in: Reformat copyright.
+
+1997-08-19 15:22 Ulrich Drepper <drepper@cygnus.com>
+
+ * dcgettext.c (DCGETTEXT): Remove wrong comment.
+
+1997-08-16 00:13 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install-data): Don't change directory to install.
+
+1997-08-01 14:30 Ulrich Drepper <drepper@cygnus.com>
+
+ * cat-compat.c: Fix copyright.
+
+ * localealias.c: Don't define strchr unless !HAVE_STRCHR.
+
+ * loadmsgcat.c: Update copyright. Fix typos.
+
+ * l10nflist.c: Don't define strchr unless !HAVE_STRCHR.
+ (_nl_make_l10nflist): Handle sponsor and revision correctly.
+
+ * gettext.c: Update copyright.
+ * gettext.h: Likewise.
+ * hash-string.h: Likewise.
+
+ * finddomain.c: Remoave dead code. Define strchr only if
+ !HAVE_STRCHR.
+
+ * explodename.c: Include <sys/types.h>.
+
+ * explodename.c: Reformat copyright text.
+ (_nl_explode_name): Fix typo.
+
+ * dcgettext.c: Define and use __set_errno.
+ (guess_category_value): Don't use setlocale if HAVE_LC_MESSAGES is
+ not defined.
+
+ * bindtextdom.c: Pretty printing.
+
+1997-05-01 02:25 Ulrich Drepper <drepper@cygnus.com>
+
+ * dcgettext.c (guess_category_value): Don't depend on
+ HAVE_LC_MESSAGES. We don't need the macro here.
+ Patch by Bruno Haible <haible@ilog.fr>.
+
+ * cat-compat.c (textdomain): DoN't refer to HAVE_SETLOCALE_NULL
+ macro. Instead use HAVE_LOCALE_NULL and define it when using
+ glibc, as in dcgettext.c.
+ Patch by Bruno Haible <haible@ilog.fr>.
+
+ * Makefile.in (CPPFLAGS): New variable. Reported by Franc,ois
+ Pinard.
+
+Mon Mar 10 06:51:17 1997 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in: Implement handling of libtool.
+
+ * gettextP.h: Change data structures for use of generic lowlevel
+ i18n file handling.
+
+Wed Dec 4 20:21:18 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * textdomain.c: Put parentheses around arguments of memcpy macro
+ definition.
+ * localealias.c: Likewise.
+ * l10nflist.c: Likewise.
+ * finddomain.c: Likewise.
+ * bindtextdom.c: Likewise.
+ Reported by Thomas Esken.
+
+Mon Nov 25 22:57:51 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * textdomain.c: Move definition of `memcpy` macro to right
+ position.
+
+Fri Nov 22 04:01:58 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * finddomain.c [!HAVE_STRING_H && !_LIBC]: Define memcpy using
+ bcopy if not already defined. Reported by Thomas Esken.
+ * bindtextdom.c: Likewise.
+ * l10nflist.c: Likewise.
+ * localealias.c: Likewise.
+ * textdomain.c: Likewise.
+
+Tue Oct 29 11:10:27 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (libdir): Change to use exec_prefix instead of
+ prefix. Reported by Knut-HåvardAksnes <etokna@eto.ericsson.se>.
+
+Sat Aug 31 03:07:09 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c (_nl_normalize_codeset): We convert to lower case,
+ so don't prepend uppercase `ISO' for only numeric arg.
+
+Fri Jul 19 00:15:46 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c: Move inclusion of argz.h, ctype.h, stdlib.h after
+ definition of _GNU_SOURCE. Patch by Roland McGrath.
+
+ * Makefile.in (uninstall): Fix another bug with `for' loop and
+ empty arguments. Patch by Jim Meyering. Correct name os
+ uninstalled files: no intl- prefix anymore.
+
+ * Makefile.in (install-data): Again work around shells which
+ cannot handle mpty for list. Reported by Jim Meyering.
+
+Sat Jul 13 18:11:35 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install): Split goal. Now depend on install-exec
+ and install-data.
+ (install-exec, install-data): New goals. Created from former
+ install goal.
+ Reported by Karl Berry.
+
+Sat Jun 22 04:58:14 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (MKINSTALLDIRS): New variable. Path to
+ mkinstalldirs script.
+ (install): use MKINSTALLDIRS variable or if the script is not present
+ try to find it in the $top_scrdir).
+
+Wed Jun 19 02:56:56 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c: Linux libc *partly* includes the argz_* functions.
+ Grr. Work around by renaming the static version and use macros
+ for renaming.
+
+Tue Jun 18 20:11:17 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c: Correct presence test macros of __argz_* functions.
+
+ * l10nflist.c: Include <argz.h> based on test of it instead when
+ __argz_* functions are available.
+ Reported by Andreas Schwab.
+
+Thu Jun 13 15:17:44 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * explodename.c, l10nflist.c: Define NULL for dumb systems.
+
+Tue Jun 11 17:05:13 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in, libgettext.h (dcgettext): Rename local variable
+ result to __result to prevent name clash.
+
+ * l10nflist.c, localealias.c, dcgettext.c: Define _GNU_SOURCE to
+ get prototype for stpcpy and strcasecmp.
+
+ * intlh.inst.in, libgettext.h: Move declaration of
+ `_nl_msg_cat_cntr' outside __extension__ block to prevent warning
+ from gcc's -Wnested-extern option.
+
+Fri Jun 7 01:58:00 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install): Remove comment.
+
+Thu Jun 6 17:28:17 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install): Work around for another Buglix stupidity.
+ Always use an `else' close for `if's. Reported by Nelson Beebe.
+
+ * Makefile.in (intlh.inst): Correct typo in phony rule.
+ Reported by Nelson Beebe.
+
+Thu Jun 6 01:49:52 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * dcgettext.c (read_alias_file): Rename variable alloca_list to
+ block_list as the macro calls assume.
+ Patch by Eric Backus.
+
+ * localealias.c [!HAVE_ALLOCA]: Define alloca as macro using
+ malloc.
+ (read_alias_file): Rename varriabe alloca_list to block_list as the
+ macro calls assume.
+ Patch by Eric Backus.
+
+ * l10nflist.c: Correct conditional for <argz.h> inclusion.
+ Reported by Roland McGrath.
+
+ * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not
+ all-@USE_NLS@.
+
+ * Makefile.in (install): intlh.inst comes from local dir, not
+ $(srcdir).
+
+ * Makefile.in (intlh.inst): Special handling of this goal. If
+ used in gettext, this is really a rul to construct this file. If
+ used in any other package it is defined as a .PHONY rule with
+ empty body.
+
+ * finddomain.c: Extract locale file information handling into
+ l10nfile.c. Rename local stpcpy__ function to stpcpy.
+
+ * dcgettext.c (stpcpy): Add local definition.
+
+ * l10nflist.c: Solve some portability problems. Patches partly by
+ Thomas Esken. Add local definition of stpcpy.
+
+Tue Jun 4 02:47:49 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in: Don't depend including <locale.h> on
+ HAVE_LOCALE_H. Instead configure must rewrite this fiile
+ depending on the result of the configure run.
+
+ * Makefile.in (install): libintl.inst is now called intlh.inst.
+ Add rules for updating intlh.inst from intlh.inst.in.
+
+ * libintl.inst: Renamed to intlh.inst.in.
+
+ * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1
+ because gcc has __buitlin_alloca.
+ Reported by Roland McGrath.
+
+Mon Jun 3 00:32:16 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (installcheck): New goal to fulfill needs of
+ automake's distcheck.
+
+ * Makefile.in (install): Reorder commands so that VERSION is
+ found.
+
+ * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in
+ @datadir@/gettext.
+ (COMSRCS): Add l10nfile.c.
+ (OBJECTS): Add l10nfile.o.
+ (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common).
+ (DISTFILE.gettext): Remove $(DISTFILES.common).
+ (all-gettext): Remove goal.
+ (install): If $(PACKAGE) = gettext install, otherwose do nothing. No
+ package but gettext itself should install libintl.h + headers.
+ (dist): Extend goal to work for gettext, too.
+ (dist-gettext): Remove goal.
+
+ * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc.
+
+Sun Jun 2 17:33:06 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * loadmsgcat.c (_nl_load_domain): Parameter is now comes from
+ find_l10nfile.
+
+Sat Jun 1 02:23:03 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c (__argz_next): Add definition.
+
+ * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca
+ code. Use new l10nfile handling.
+
+ * localealias.c [!HAVE_ALLOCA]: Add code for handling missing
+ alloca code.
+
+ * l10nflist.c: Initial revision.
+
+Tue Apr 2 18:51:18 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all-gettext): New goal. Same as all-yes.
+
+Thu Mar 28 23:01:22 1996 Karl Eichwalder <ke@ke.central.de>
+
+ * Makefile.in (gettextsrcdir): Define using @datadir@.
+
+Tue Mar 26 12:39:14 1996 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c: Include <ctype.h>. Reported by Roland McGrath.
+
+Sat Mar 23 02:00:35 1996 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (stpcpy): Rename to stpcpy__ to prevent clashing
+ with external declaration.
+
+Sat Mar 2 00:47:09 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all-no): Rename from all_no.
+
+Sat Feb 17 00:25:59 1996 Ulrich Drepper <drepper@myware>
+
+ * gettextP.h [loaded_domain]: Array `successor' must now contain up
+ to 63 elements (because of codeset name normalization).
+
+ * finddomain.c: Implement codeset name normalization.
+
+Thu Feb 15 04:39:09 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all): Define to `all-@USE_NLS@'.
+ (all-yes, all_no): New goals. `all-no' is noop, `all-yes'
+ is former all.
+
+Mon Jan 15 21:46:01 1996 Howard Gayle <howard@hal.com>
+
+ * localealias.c (alias_compare): Increment string pointers in loop
+ of strcasecmp replacement.
+
+Fri Dec 29 21:16:34 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src): Who commented this goal out ? :-)
+
+Fri Dec 29 15:08:16 1995 Ulrich Drepper <drepper@myware>
+
+ * dcgettext.c (DCGETTEXT): Save `errno'. Failing system calls
+ should not effect it because a missing catalog is no error.
+ Reported by Harald K<o:>nig <koenig@tat.physik.uni-tuebingen.de>.
+
+Tue Dec 19 22:09:13 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (Makefile): Explicitly use $(SHELL) for running
+ shell scripts.
+
+Fri Dec 15 17:34:59 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Makefile.in (install-src): Only install library and header when
+ we use the own implementation. Don't do it when using the
+ system's gettext or catgets functions.
+
+ * dcgettext.c (find_msg): Must not swap domain->hash_size here.
+
+Sat Dec 9 16:24:37 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c, libintl.inst, libgettext.h, hash-string.h,
+ gettextP.h, finddomain.c, dcgettext.c, cat-compat.c:
+ Use PARAMS instead of __P. Suggested by Roland McGrath.
+
+Tue Dec 5 11:39:14 1995 Larry Schwimmer <rosebud@cyclone.stanford.edu>
+
+ * libgettext.h: Use `#if !defined (_LIBINTL_H)' instead of `#if
+ !_LIBINTL_H' because Solaris defines _LIBINTL_H as empty.
+
+Mon Dec 4 15:42:07 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src):
+ Install libintl.inst instead of libintl.h.install.
+
+Sat Dec 2 22:51:38 1995 Marcus Daniels <marcus@sysc.pdx.edu>
+
+ * cat-compat.c (textdomain):
+ Reverse order in which files are tried you load. First
+ try local file, when this failed absolute path.
+
+Wed Nov 29 02:03:53 1995 Nelson H. F. Beebe <beebe@math.utah.edu>
+
+ * cat-compat.c (bindtextdomain): Add missing { }.
+
+Sun Nov 26 18:21:41 1995 Ulrich Drepper <drepper@myware>
+
+ * libintl.inst: Add missing __P definition. Reported by Nelson Beebe.
+
+ * Makefile.in:
+ Add dummy `all' and `dvi' goals. Reported by Tom Tromey.
+
+Sat Nov 25 16:12:01 1995 Franc,ois Pinard <pinard@iro.umontreal.ca>
+
+ * hash-string.h: Capitalize arguments of macros.
+
+Sat Nov 25 12:01:36 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Prevent files names longer than 13
+ characters. libintl.h.glibc->libintl.glibc,
+ libintl.h.install->libintl.inst. Reported by Joshua R. Poulson.
+
+Sat Nov 25 11:31:12 1995 Eric Backus <ericb@lsid.hp.com>
+
+ * dcgettext.c: Fix bug in preprocessor conditionals.
+
+Sat Nov 25 02:35:27 1995 Nelson H. F. Beebe <beebe@math.utah.edu>
+
+ * libgettext.h: Solaris cc does not understand
+ #if !SYMBOL1 && !SYMBOL2. Sad but true.
+
+Thu Nov 23 16:22:14 1995 Ulrich Drepper <drepper@myware>
+
+ * hash-string.h (hash_string):
+ Fix for machine with >32 bit `unsigned long's.
+
+ * dcgettext.c (DCGETTEXT):
+ Fix horrible bug in loop for alternative translation.
+
+Thu Nov 23 01:45:29 1995 Ulrich Drepper <drepper@myware>
+
+ * po2tbl.sed.in, linux-msg.sed, xopen-msg.sed:
+ Some further simplifications in message number generation.
+
+Mon Nov 20 21:08:43 1995 Ulrich Drepper <drepper@myware>
+
+ * libintl.h.glibc: Use __const instead of const in prototypes.
+
+ * Makefile.in (install-src):
+ Install libintl.h.install instead of libintl.h. This
+ is a stripped-down version. Suggested by Peter Miller.
+
+ * libintl.h.install, libintl.h.glibc: Initial revision.
+
+ * localealias.c (_nl_expand_alias, read_alias_file):
+ Protect prototypes in type casts by __P.
+
+Tue Nov 14 16:43:58 1995 Ulrich Drepper <drepper@myware>
+
+ * hash-string.h: Correct prototype for hash_string.
+
+Sun Nov 12 12:42:30 1995 Ulrich Drepper <drepper@myware>
+
+ * hash-string.h (hash_string): Add prototype.
+
+ * gettextP.h: Fix copyright.
+ (SWAP): Add prototype.
+
+Wed Nov 8 22:56:33 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (read_alias_file): Forgot sizeof.
+ Avoid calling *printf function. This introduces a big overhead.
+ Patch by Roland McGrath.
+
+Tue Nov 7 14:21:08 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c, cat-compat.c: Wrong indentation in #if for stpcpy.
+
+ * finddomain.c (stpcpy):
+ Define substitution function local. The macro was to flaky.
+
+ * cat-compat.c: Fix typo.
+
+ * xopen-msg.sed, linux-msg.sed:
+ While bringing message number to right place only accept digits.
+
+ * linux-msg.sed, xopen-msg.sed: Now that the counter does not have
+ leading 0s we don't need to remove them. Reported by Marcus
+ Daniels.
+
+ * Makefile.in (../po/cat-id-tbl.o): Use $(top_srdir) in
+ dependency. Reported by Marcus Daniels.
+
+ * cat-compat.c: (stpcpy) [!_LIBC && !HAVE_STPCPY]: Define replacement.
+ Generally cleanup using #if instead of #ifndef.
+
+ * Makefile.in: Correct typos in comment. By Franc,ois Pinard.
+
+Mon Nov 6 00:27:02 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src): Don't install libintl.h and libintl.a
+ if we use an available gettext implementation.
+
+Sun Nov 5 22:02:08 1995 Ulrich Drepper <drepper@myware>
+
+ * libgettext.h: Fix typo: HAVE_CATGETTS -> HAVE_CATGETS. Reported
+ by Franc,ois Pinard.
+
+ * libgettext.h: Use #if instead of #ifdef/#ifndef.
+
+ * finddomain.c:
+ Comments describing what has to be done should start with FIXME.
+
+Sun Nov 5 19:38:01 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Split. Use DISTFILES with normal meaning.
+ DISTFILES.common names the files common to both dist goals.
+ DISTFILES.gettext are the files only distributed in GNU gettext.
+
+Sun Nov 5 17:32:54 1995 Ulrich Drepper <drepper@myware>
+
+ * dcgettext.c (DCGETTEXT): Correct searching in derived locales.
+ This was necessary since a change in _nl_find_msg several weeks
+ ago. I really don't know this is still not fixed.
+
+Sun Nov 5 12:43:12 1995 Ulrich Drepper <drepper@myware>
+
+ * loadmsgcat.c (_nl_load_domain): Test for FILENAME == NULL. This
+ might mark a special condition.
+
+ * finddomain.c (make_entry_rec): Don't make illegal entry as decided.
+
+ * Makefile.in (dist): Suppress error message when ln failed.
+ Get files from $(srcdir) explicitly.
+
+ * libgettext.h (gettext_const): Rename to gettext_noop.
+
+Fri Nov 3 07:36:50 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (make_entry_rec):
+ Protect against wrong locale names by testing mask.
+
+ * libgettext.h (gettext_const): Add macro definition.
+ Capitalize macro arguments.
+
+Thu Nov 2 23:15:51 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (_nl_find_domain):
+ Test for pointer != NULL before accessing value.
+ Reported by Tom Tromey.
+
+ * gettext.c (NULL):
+ Define as (void*)0 instad of 0. Reported by Franc,ois Pinard.
+
+Mon Oct 30 21:28:52 1995 Ulrich Drepper <drepper@myware>
+
+ * po2tbl.sed.in: Serious typo bug fixed by Jim Meyering.
+
+Sat Oct 28 23:20:47 1995 Ulrich Drepper <drepper@myware>
+
+ * libgettext.h: Disable dcgettext optimization for Solaris 2.3.
+
+ * localealias.c (alias_compare):
+ Peter Miller reported that tolower in some systems is
+ even dumber than I thought. Protect call by `isupper'.
+
+Fri Oct 27 22:22:51 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (libdir, includedir): New variables.
+ (install-src): Install libintl.a and libintl.h in correct dirs.
+
+Fri Oct 27 22:07:29 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (SOURCES): Fix typo: intrl.compat.c -> intl-compat.c.
+
+ * po2tbl.sed.in: Patch for buggy SEDs by Christian von Roques.
+
+ * localealias.c:
+ Fix typo and superflous test. Reported by Christian von Roques.
+
+Fri Oct 6 11:52:05 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (_nl_find_domain):
+ Correct some remainder from the pre-CEN syntax. Now
+ we don't have a constant number of successors anymore.
+
+Wed Sep 27 21:41:13 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Add libintl.h.glibc.
+
+ * Makefile.in (dist-libc): Add goal for packing sources for glibc.
+ (COMSRCS, COMHDRS): Splitted to separate sources shared with glibc.
+
+ * loadmsgcat.c: Forget to continue #if line.
+
+ * localealias.c:
+ [_LIBC]: Rename strcasecmp to __strcasecmp to keep ANSI C name
+ space clean.
+
+ * dcgettext.c, finddomain.c: Better comment to last change.
+
+ * loadmsgcat.c:
+ [_LIBC]: Rename fstat, open, close, read, mmap, and munmap to
+ __fstat, __open, __close, __read, __mmap, and __munmap resp
+ to keep ANSI C name space clean.
+
+ * finddomain.c:
+ [_LIBC]: Rename stpcpy to __stpcpy to keep ANSI C name space clean.
+
+ * dcgettext.c:
+ [_LIBC]: Rename getced and stpcpy to __getcwd and __stpcpy resp to
+ keep ANSI C name space clean.
+
+ * libgettext.h:
+ Include sys/types.h for those old SysV systems out there.
+ Reported by Francesco Potorti`.
+
+ * loadmsgcat.c (use_mmap): Define if compiled for glibc.
+
+ * bindtextdom.c: Include all those standard headers
+ unconditionally if _LIBC is defined.
+
+ * finddomain.c: Fix 2 times defiend -> defined.
+
+ * textdomain.c: Include libintl.h instead of libgettext.h when
+ compiling for glibc. Include all those standard headers
+ unconditionally if _LIBC is defined.
+
+ * localealias.c, loadmsgcat.c: Prepare to be compiled in glibc.
+
+ * gettext.c:
+ Include libintl.h instead of libgettext.h when compiling for glibc.
+ Get NULL from stddef.h if we compile for glibc.
+
+ * finddomain.c: Include libintl.h instead of libgettext.h when
+ compiling for glibc. Include all those standard headers
+ unconditionally if _LIBC is defined.
+
+ * dcgettext.c: Include all those standard headers unconditionally
+ if _LIBC is defined.
+
+ * dgettext.c: If compiled in glibc include libintl.h instead of
+ libgettext.h.
+ (locale.h): Don't rely on HAVE_LOCALE_H when compiling for glibc.
+
+ * dcgettext.c: If compiled in glibc include libintl.h instead of
+ libgettext.h.
+ (getcwd): Don't rely on HAVE_GETCWD when compiling for glibc.
+
+ * bindtextdom.c:
+ If compiled in glibc include libintl.h instead of libgettext.h.
+
+Mon Sep 25 22:23:06 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (_nl_expand_alias): Don't call bsearch if NMAP <= 0.
+ Reported by Marcus Daniels.
+
+ * cat-compat.c (bindtextdomain):
+ String used in putenv must not be recycled.
+ Reported by Marcus Daniels.
+
+ * libgettext.h (__USE_GNU_GETTEXT):
+ Additional symbol to signal that we use GNU gettext
+ library.
+
+ * cat-compat.c (bindtextdomain):
+ Fix bug with the strange stpcpy replacement.
+ Reported by Nelson Beebe.
+
+Sat Sep 23 08:23:51 1995 Ulrich Drepper <drepper@myware>
+
+ * cat-compat.c: Include <string.h> for stpcpy prototype.
+
+ * localealias.c (read_alias_file):
+ While expand strdup code temporary variable `cp' hided
+ higher level variable with same name. Rename to `tp'.
+
+ * textdomain.c (textdomain):
+ Avoid warning by using temporary variable in strdup code.
+
+ * finddomain.c (_nl_find_domain): Remove unused variable `application'.
+
+Thu Sep 21 15:51:44 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (alias_compare):
+ Use strcasecmp() only if available. Else use
+ implementation in place.
+
+ * intl-compat.c:
+ Wrapper functions now call *__ functions instead of __*.
+
+ * libgettext.h: Declare prototypes for *__ functions instead for __*.
+
+ * cat-compat.c, loadmsgcat.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+
+ * bindtextdom.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+ Rename to bindtextdomain__ if not used in GNU C Library.
+
+ * dgettext.c:
+ Rename function to dgettext__ if not used in GNU C Library.
+
+ * gettext.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+ Functions now called gettext__ if not used in GNU C Library.
+
+ * dcgettext.c, localealias.c, textdomain.c, finddomain.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+
+Sun Sep 17 23:14:49 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c: Correct some bugs in handling of CEN standard
+ locale definitions.
+
+Thu Sep 7 01:49:28 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c: Implement CEN syntax.
+
+ * gettextP.h (loaded_domain): Extend number of successors to 31.
+
+Sat Aug 19 19:25:29 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (aliaspath): Remove path to X11 locale dir.
+
+ * Makefile.in: Make install-src depend on install. This helps
+ gettext to install the sources and other packages can use the
+ install goal.
+
+Sat Aug 19 15:19:33 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (uninstall): Remove stuff installed by install-src.
+
+Tue Aug 15 13:13:53 1995 Ulrich Drepper <drepper@myware>
+
+ * VERSION.in: Initial revision.
+
+ * Makefile.in (DISTFILES):
+ Add VERSION file. This is not necessary for gettext, but
+ for other packages using this library.
+
+Tue Aug 15 06:16:44 1995 Ulrich Drepper <drepper@myware>
+
+ * gettextP.h (_nl_find_domain):
+ New prototype after changing search strategy.
+
+ * finddomain.c (_nl_find_domain):
+ We now try only to find a specified catalog. Fall back to other
+ catalogs listed in the locale list is now done in __dcgettext.
+
+ * dcgettext.c (__dcgettext):
+ Now we provide message fall back even to different languages.
+ I.e. if a message is not available in one language all the other
+ in the locale list a tried. Formerly fall back was only possible
+ within one language. Implemented by moving one loop from
+ _nl_find_domain to here.
+
+Mon Aug 14 23:45:50 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (gettextsrcdir):
+ Directory where source of GNU gettext library are made
+ available.
+ (INSTALL, INSTALL_DATA): Programs used for installing sources.
+ (gettext-src): New. Rule to install GNU gettext sources for use in
+ gettextize shell script.
+
+Sun Aug 13 14:40:48 1995 Ulrich Drepper <drepper@myware>
+
+ * loadmsgcat.c (_nl_load_domain):
+ Use mmap for loading only when munmap function is
+ also available.
+
+ * Makefile.in (install): Depend on `all' goal.
+
+Wed Aug 9 11:04:33 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (read_alias_file):
+ Do not overwrite '\n' when terminating alias value string.
+
+ * localealias.c (read_alias_file):
+ Handle long lines. Ignore the rest not fitting in
+ the buffer after the initial `fgets' call.
+
+Wed Aug 9 00:54:29 1995 Ulrich Drepper <drepper@myware>
+
+ * gettextP.h (_nl_load_domain):
+ Add prototype, replacing prototype for _nl_load_msg_cat.
+
+ * finddomain.c (_nl_find_domain):
+ Remove unneeded variable filename and filename_len.
+ (expand_alias): Remove prototype because functions does not
+ exist anymore.
+
+ * localealias.c (read_alias_file):
+ Change type of fname_len parameter to int.
+ (xmalloc): Add prototype.
+
+ * loadmsgcat.c: Better prototypes for xmalloc.
+
+Tue Aug 8 22:30:39 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (_nl_find_domain):
+ Allow alias name to be constructed from the four components.
+
+ * Makefile.in (aliaspath): New variable. Set to preliminary value.
+ (SOURCES): Add localealias.c.
+ (OBJECTS): Add localealias.o.
+
+ * gettextP.h: Add prototype for _nl_expand_alias.
+
+ * finddomain.c: Aliasing handled in intl/localealias.c.
+
+ * localealias.c: Aliasing for locale names.
+
+ * bindtextdom.c: Better prototypes for xmalloc and xstrdup.
+
+Mon Aug 7 23:47:42 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): gettext.perl is now found in misc/.
+
+ * cat-compat.c (bindtextdomain):
+ Correct implementation. dirname parameter was not used.
+ Reported by Marcus Daniels.
+
+ * gettextP.h (loaded_domain):
+ New fields `successor' and `decided' for oo, lazy
+ message handling implementation.
+
+ * dcgettext.c:
+ Adopt for oo, lazy message handliing.
+ Now we can inherit translations from less specific locales.
+ (find_msg): New function.
+
+ * loadmsgcat.c, finddomain.c:
+ Complete rewrite. Implement oo, lazy message handling :-).
+ We now have an additional environment variable `LANGUAGE' with
+ a higher priority than LC_ALL for the LC_MESSAGE locale.
+ Here we can set a colon separated list of specifications each
+ of the form `language[_territory[.codeset]][@modifier]'.
+
+Sat Aug 5 09:55:42 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (unistd.h):
+ Include to get _PC_PATH_MAX defined on system having it.
+
+Fri Aug 4 22:42:00 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (stpcpy): Include prototype.
+
+ * Makefile.in (dist): Remove `copying instead' message.
+
+Wed Aug 2 18:52:03 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (ID, TAGS): Do not use $^.
+
+Tue Aug 1 20:07:11 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (TAGS, ID): Use $^ as command argument.
+ (TAGS): Give etags -o option t write to current directory,
+ not $(srcdir).
+ (ID): Use $(srcdir) instead os $(top_srcdir)/src.
+ (distclean): Remove ID.
+
+Sun Jul 30 11:51:46 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (gnulocaledir):
+ New variable, always using share/ for data directory.
+ (DEFS): Add GNULOCALEDIR, used in finddomain.c.
+
+ * finddomain.c (_nl_default_dirname):
+ Set to GNULOCALEDIR, because it always has to point
+ to the directory where GNU gettext Library writes it to.
+
+ * intl-compat.c (textdomain, bindtextdomain):
+ Undefine macros before function definition.
+
+Sat Jul 22 01:10:02 1995 Ulrich Drepper <drepper@myware>
+
+ * libgettext.h (_LIBINTL_H):
+ Protect definition in case where this file is included as
+ libgettext.h on Solaris machines. Add comment about this.
+
+Wed Jul 19 02:36:42 1995 Ulrich Drepper <drepper@myware>
+
+ * intl-compat.c (textdomain): Correct typo.
+
+Wed Jul 19 01:51:35 1995 Ulrich Drepper <drepper@myware>
+
+ * dcgettext.c (dcgettext): Function now called __dcgettext.
+
+ * dgettext.c (dgettext): Now called __dgettext and calls
+ __dcgettext.
+
+ * gettext.c (gettext):
+ Function now called __gettext and calls __dgettext.
+
+ * textdomain.c (textdomain): Function now called __textdomain.
+
+ * bindtextdom.c (bindtextdomain): Function now called
+ __bindtextdomain.
+
+ * intl-compat.c: Initial revision.
+
+ * Makefile.in (SOURCES): Add intl-compat.c.
+ (OBJECTS): We always compile the GNU gettext library functions.
+ OBJECTS contains all objects but cat-compat.o, ../po/cat-if-tbl.o,
+ and intl-compat.o.
+ (GETTOBJS): Contains now only intl-compat.o.
+
+ * libgettext.h:
+ Re-include protection matches dualistic character of libgettext.h.
+ For all functions in GNU gettext library define __ counter part.
+
+ * finddomain.c (strchr): Define as index if not found in C library.
+ (_nl_find_domain): For relative paths paste / in between.
+
+Tue Jul 18 16:37:45 1995 Ulrich Drepper <drepper@myware>
+
+ * loadmsgcat.c, finddomain.c: Add inclusion of sys/types.h.
+
+ * xopen-msg.sed: Fix bug with `msgstr ""' lines.
+ A little bit better comments.
+
+Tue Jul 18 01:18:27 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in:
+ po-mode.el, makelinks, combine-sh are now found in ../misc.
+
+ * po-mode.el, makelinks, combine-sh, elisp-comp:
+ Moved to ../misc/.
+
+ * libgettext.h, gettextP.h, gettext.h: Uniform test for __STDC__.
+
+Sun Jul 16 22:33:02 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (INSTALL, INSTALL_DATA): New variables.
+ (install-data, uninstall): Install/uninstall .elc file.
+
+ * po-mode.el (Installation comment):
+ Add .pox as possible extension of .po files.
+
+Sun Jul 16 13:23:27 1995 Ulrich Drepper <drepper@myware>
+
+ * elisp-comp: Complete new version by Franc,ois: This does not
+ fail when not compiling in the source directory.
+
+Sun Jul 16 00:12:17 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (../po/cat-id-tbl.o):
+ Use $(MAKE) instead of make for recursive make.
+
+ * Makefile.in (.el.elc): Use $(SHELL) instead of /bin/sh.
+ (install-exec): Add missing dummy goal.
+ (install-data, uninstall): @ in multi-line shell command at
+ beginning, not in front of echo. Reported by Eric Backus.
+
+Sat Jul 15 00:21:28 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES):
+ Rename libgettext.perl to gettext.perl to fit in 14 chars
+ file systems.
+
+ * gettext.perl:
+ Rename to gettext.perl to fit in 14 chars file systems.
+
+Thu Jul 13 23:17:20 1995 Ulrich Drepper <drepper@myware>
+
+ * cat-compat.c: If !STDC_HEADERS try to include malloc.h.
+
+Thu Jul 13 20:55:02 1995 Ulrich Drepper <drepper@myware>
+
+ * po2tbl.sed.in: Pretty printing.
+
+ * linux-msg.sed, xopen-msg.sed:
+ Correct bugs with handling substitute flags in branches.
+
+ * hash-string.h (hash_string):
+ Old K&R compilers don't under stand `unsigned char'.
+
+ * gettext.h (nls_uint32):
+ Some old K&R compilers (eg HP) don't understand `unsigned int'.
+
+ * cat-compat.c (msg_to_cat_id): De-ANSI-fy prototypes.
+
+Thu Jul 13 01:34:33 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (ELCFILES): New variable.
+ (DISTFILES): Add elisp-comp.
+ Add implicit rule for .el -> .elc compilation.
+ (install-data): install $ELCFILES
+ (clean): renamed po-to-tbl and po-to-msg to po2tbl and po2msg resp.
+
+ * elisp-comp: Initial revision
+
+Wed Jul 12 16:14:52 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in:
+ cat-id-tbl.c is now found in po/. This enables us to use an identical
+ intl/ directory in all packages.
+
+ * dcgettext.c (dcgettext): hashing does not work for table size <= 2.
+
+ * textdomain.c: fix typo (#if def -> #if defined)
+
+Tue Jul 11 18:44:43 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (stamp-cat-id): use top_srcdir to address source files
+ (DISTFILES,distclean): move tupdate.perl to src/
+
+ * po-to-tbl.sed.in:
+ add additional jump to clear change flag to recognize multiline strings
+
+Tue Jul 11 01:32:50 1995 Ulrich Drepper <drepper@myware>
+
+ * textdomain.c: Protect inclusion of stdlib.h and string.h.
+
+ * loadmsgcat.c: Protect inclusion of stdlib.h.
+
+ * libgettext.h: Protect inclusion of locale.h.
+ Allow use in C++ programs.
+ Define NULL is not happened already.
+
+ * Makefile.in (DISTFILES): ship po-to-tbl.sed.in instead of
+ po-to-tbl.sed.
+ (distclean): remove po-to-tbl.sed and tupdate.perl.
+
+ * tupdate.perl.in: Substitute Perl path even in exec line.
+ Don't include entries without translation from old .po file.
+
+Tue Jul 4 00:41:51 1995 Ulrich Drepper <drepper@myware>
+
+ * tupdate.perl.in: use "Updated: " in msgid "".
+
+ * cat-compat.c: Fix typo (LOCALDIR -> LOCALEDIR).
+ Define getenv if !__STDC__.
+
+ * bindtextdom.c: Protect stdlib.h and string.h inclusion.
+ Define free if !__STDC__.
+
+ * finddomain.c: Change DEF_MSG_DOM_DIR to LOCALEDIR.
+ Define free if !__STDC__.
+
+ * cat-compat.c: Change DEF_MSG_DOM_DIR to LOCALEDIR.
+
+Mon Jul 3 23:56:30 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in: Use LOCALEDIR instead of DEF_MSG_DOM_DIR.
+ Remove unneeded $(srcdir) from Makefile.in dependency.
+
+ * makelinks: Add copyright and short description.
+
+ * po-mode.el: Last version for 0.7.
+
+ * tupdate.perl.in: Fix die message.
+
+ * dcgettext.c: Protect include of string.h.
+
+ * gettext.c: Protect include of stdlib.h and further tries to get NULL.
+
+ * finddomain.c: Some corrections in includes.
+
+ * Makefile.in (INCLUDES): Prune list correct path to Makefile.in.
+
+ * po-to-tbl.sed: Adopt for new .po file format.
+
+ * linux-msg.sed, xopen-msg.sed: Adopt for new .po file format.
+
+Sun Jul 2 23:55:03 1995 Ulrich Drepper <drepper@myware>
+
+ * tupdate.perl.in: Complete rewrite for new .po file format.
+
+Sun Jul 2 02:06:50 1995 Ulrich Drepper <drepper@myware>
+
+ * First official release. This directory contains all the code
+ needed to internationalize own packages. It provides functions
+ which allow to use the X/Open catgets function with an interface
+ like the Uniforum gettext function. For system which does not
+ have neither of those a complete implementation is provided.
diff --git a/current/intl/Makefile.in b/current/intl/Makefile.in
new file mode 100644
index 00000000..4bdb186d
--- /dev/null
+++ b/current/intl/Makefile.in
@@ -0,0 +1,214 @@
+# Makefile for directory with message catalog handling in GNU NLS Utilities.
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = ..
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+transform = @program_transform_name@
+libdir = $(exec_prefix)/lib
+includedir = $(prefix)/include
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = @datadir@/gettext/intl
+aliaspath = $(localedir):.
+subdir = intl
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+l = @l@
+
+AR = ar
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+RANLIB = @RANLIB@
+
+DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \
+-DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@
+CPPFLAGS = @CPPFLAGS@
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+HEADERS = $(COMHDRS) libgettext.h loadinfo.h
+COMHDRS = gettext.h gettextP.h hash-string.h
+SOURCES = $(COMSRCS) intl-compat.c cat-compat.c
+COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \
+finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \
+explodename.c
+OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \
+finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \
+explodename.$lo
+CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo
+GETTOBJS = intl-compat.$lo
+DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \
+xopen-msg.sed $(HEADERS) $(SOURCES)
+DISTFILES.normal = VERSION
+DISTFILES.gettext = libintl.glibc intlh.inst.in
+
+.SUFFIXES:
+.SUFFIXES: .c .o .lo
+.c.o:
+ $(COMPILE) $<
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) $<
+
+INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib
+
+all: all-@USE_INCLUDED_LIBINTL@
+
+all-yes: libintl.$la intlh.inst
+all-no:
+
+libintl.a: $(OBJECTS)
+ rm -f $@
+ $(AR) cru $@ $(OBJECTS)
+ $(RANLIB) $@
+
+libintl.la: $(OBJECTS)
+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \
+ -version-info 1:0 -rpath $(libdir)
+
+../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot
+ cd ../po && $(MAKE) cat-id-tbl.$lo
+
+check: all
+
+# This installation goal is only used in GNU gettext. Packages which
+# only use the library should use install instead.
+
+# We must not install the libintl.h/libintl.a files if we are on a
+# system which has the gettext() function in its C library or in a
+# separate library or use the catgets interface. A special case is
+# where configure found a previously installed GNU gettext library.
+# If you want to use the one which comes with this version of the
+# package, you have to use `configure --with-included-gettext'.
+install: install-exec install-data
+install-exec: all
+ if test "$(PACKAGE)" = "gettext" \
+ && test '@INTLOBJS@' = '$(GETTOBJS)'; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(libdir) $(includedir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \
+ fi; \
+ $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \
+ $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \
+ else \
+ : ; \
+ fi
+install-data: all
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \
+ dists="$(DISTFILES.common)"; \
+ for file in $$dists; do \
+ $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ dists="$(DISTFILES.common)"; \
+ for file in $$dists; do \
+ rm -f $(gettextsrcdir)/$$file; \
+ done
+
+info dvi:
+
+$(OBJECTS): ../config.h libgettext.h
+bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h
+dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h
+
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES)
+ here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES)
+
+id: ID
+
+ID: $(HEADERS) $(SOURCES)
+ here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES)
+
+
+mostlyclean:
+ rm -f *.a *.o *.lo core core.*
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile ID TAGS po2msg.sed po2tbl.sed
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+
+# GNU gettext needs not contain the file `VERSION' but contains some
+# other files which should not be distributed in other packages.
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: Makefile $(DISTFILES)
+ if test "$(PACKAGE)" = gettext; then \
+ additional="$(DISTFILES.gettext)"; \
+ else \
+ additional="$(DISTFILES.normal)"; \
+ fi; \
+ for file in $(DISTFILES.common) $$additional; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+dist-libc:
+ tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc
+
+Makefile: Makefile.in ../config.status
+ cd .. \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# The dependency for intlh.inst is different in gettext and all other
+# packages. Because we cannot you GNU make features we have to solve
+# the problem while rewriting Makefile.in.
+@GT_YES@intlh.inst: intlh.inst.in ../config.status
+@GT_YES@ cd .. \
+@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \
+@GT_YES@ $(SHELL) ./config.status
+@GT_NO@.PHONY: intlh.inst
+@GT_NO@intlh.inst:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/intl/VERSION b/current/intl/VERSION
new file mode 100644
index 00000000..ee66b061
--- /dev/null
+++ b/current/intl/VERSION
@@ -0,0 +1 @@
+GNU gettext library from gettext-0.10.35
diff --git a/current/intl/bindtextdom.c b/current/intl/bindtextdom.c
new file mode 100644
index 00000000..d9c3f349
--- /dev/null
+++ b/current/intl/bindtextdom.c
@@ -0,0 +1,203 @@
+/* Implementation of the bindtextdomain(3) function
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+#include "gettext.h"
+#include "gettextP.h"
+
+/* @@ end of prolog @@ */
+
+/* Contains the default location of the message catalogs. */
+extern const char _nl_default_dirname[];
+
+/* List with bindings of specific domains. */
+extern struct binding *_nl_domain_bindings;
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define BINDTEXTDOMAIN __bindtextdomain
+# ifndef strdup
+# define strdup(str) __strdup (str)
+# endif
+#else
+# define BINDTEXTDOMAIN bindtextdomain__
+#endif
+
+/* Specify that the DOMAINNAME message catalog will be found
+ in DIRNAME rather than in the system locale data base. */
+char *
+BINDTEXTDOMAIN (domainname, dirname)
+ const char *domainname;
+ const char *dirname;
+{
+ struct binding *binding;
+
+ /* Some sanity checks. */
+ if (domainname == NULL || domainname[0] == '\0')
+ return NULL;
+
+ for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
+ {
+ int compare = strcmp (domainname, binding->domainname);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It is not in the list. */
+ binding = NULL;
+ break;
+ }
+ }
+
+ if (dirname == NULL)
+ /* The current binding has be to returned. */
+ return binding == NULL ? (char *) _nl_default_dirname : binding->dirname;
+
+ if (binding != NULL)
+ {
+ /* The domain is already bound. If the new value and the old
+ one are equal we simply do nothing. Otherwise replace the
+ old binding. */
+ if (strcmp (dirname, binding->dirname) != 0)
+ {
+ char *new_dirname;
+
+ if (strcmp (dirname, _nl_default_dirname) == 0)
+ new_dirname = (char *) _nl_default_dirname;
+ else
+ {
+#if defined _LIBC || defined HAVE_STRDUP
+ new_dirname = strdup (dirname);
+ if (new_dirname == NULL)
+ return NULL;
+#else
+ size_t len = strlen (dirname) + 1;
+ new_dirname = (char *) malloc (len);
+ if (new_dirname == NULL)
+ return NULL;
+
+ memcpy (new_dirname, dirname, len);
+#endif
+ }
+
+ if (binding->dirname != _nl_default_dirname)
+ free (binding->dirname);
+
+ binding->dirname = new_dirname;
+ }
+ }
+ else
+ {
+ /* We have to create a new binding. */
+#if !defined _LIBC && !defined HAVE_STRDUP
+ size_t len;
+#endif
+ struct binding *new_binding =
+ (struct binding *) malloc (sizeof (*new_binding));
+
+ if (new_binding == NULL)
+ return NULL;
+
+#if defined _LIBC || defined HAVE_STRDUP
+ new_binding->domainname = strdup (domainname);
+ if (new_binding->domainname == NULL)
+ return NULL;
+#else
+ len = strlen (domainname) + 1;
+ new_binding->domainname = (char *) malloc (len);
+ if (new_binding->domainname == NULL)
+ return NULL;
+ memcpy (new_binding->domainname, domainname, len);
+#endif
+
+ if (strcmp (dirname, _nl_default_dirname) == 0)
+ new_binding->dirname = (char *) _nl_default_dirname;
+ else
+ {
+#if defined _LIBC || defined HAVE_STRDUP
+ new_binding->dirname = strdup (dirname);
+ if (new_binding->dirname == NULL)
+ return NULL;
+#else
+ len = strlen (dirname) + 1;
+ new_binding->dirname = (char *) malloc (len);
+ if (new_binding->dirname == NULL)
+ return NULL;
+ memcpy (new_binding->dirname, dirname, len);
+#endif
+ }
+
+ /* Now enqueue it. */
+ if (_nl_domain_bindings == NULL
+ || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
+ {
+ new_binding->next = _nl_domain_bindings;
+ _nl_domain_bindings = new_binding;
+ }
+ else
+ {
+ binding = _nl_domain_bindings;
+ while (binding->next != NULL
+ && strcmp (domainname, binding->next->domainname) > 0)
+ binding = binding->next;
+
+ new_binding->next = binding->next;
+ binding->next = new_binding;
+ }
+
+ binding = new_binding;
+ }
+
+ return binding->dirname;
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__bindtextdomain, bindtextdomain);
+#endif
diff --git a/current/intl/cat-compat.c b/current/intl/cat-compat.c
new file mode 100644
index 00000000..867d901b
--- /dev/null
+++ b/current/intl/cat-compat.c
@@ -0,0 +1,262 @@
+/* Compatibility code for gettext-using-catgets interface.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+char *getenv ();
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef HAVE_NL_TYPES_H
+# include <nl_types.h>
+#endif
+
+#include "libgettext.h"
+
+/* @@ end of prolog @@ */
+
+/* XPG3 defines the result of `setlocale (category, NULL)' as:
+ ``Directs `setlocale()' to query `category' and return the current
+ setting of `local'.''
+ However it does not specify the exact format. And even worse: POSIX
+ defines this not at all. So we can use this feature only on selected
+ system (e.g. those using GNU C Library). */
+#ifdef _LIBC
+# define HAVE_LOCALE_NULL
+#endif
+
+/* The catalog descriptor. */
+static nl_catd catalog = (nl_catd) -1;
+
+/* Name of the default catalog. */
+static const char default_catalog_name[] = "messages";
+
+/* Name of currently used catalog. */
+static const char *catalog_name = default_catalog_name;
+
+/* Get ID for given string. If not found return -1. */
+static int msg_to_cat_id PARAMS ((const char *msg));
+
+/* Substitution for systems lacking this function in their C library. */
+#if !_LIBC && !HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+#endif
+
+
+/* Set currently used domain/catalog. */
+char *
+textdomain (domainname)
+ const char *domainname;
+{
+ nl_catd new_catalog;
+ char *new_name;
+ size_t new_name_len;
+ char *lang;
+
+#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \
+ && defined HAVE_LOCALE_NULL
+ lang = setlocale (LC_MESSAGES, NULL);
+#else
+ lang = getenv ("LC_ALL");
+ if (lang == NULL || lang[0] == '\0')
+ {
+ lang = getenv ("LC_MESSAGES");
+ if (lang == NULL || lang[0] == '\0')
+ lang = getenv ("LANG");
+ }
+#endif
+ if (lang == NULL || lang[0] == '\0')
+ lang = "C";
+
+ /* See whether name of currently used domain is asked. */
+ if (domainname == NULL)
+ return (char *) catalog_name;
+
+ if (domainname[0] == '\0')
+ domainname = default_catalog_name;
+
+ /* Compute length of added path element. */
+ new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang)
+ + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1
+ + sizeof (".cat");
+
+ new_name = (char *) malloc (new_name_len);
+ if (new_name == NULL)
+ return NULL;
+
+ strcpy (new_name, PACKAGE);
+ new_catalog = catopen (new_name, 0);
+
+ if (new_catalog == (nl_catd) -1)
+ {
+ /* NLSPATH search didn't work, try absolute path */
+ sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang,
+ PACKAGE);
+ new_catalog = catopen (new_name, 0);
+
+ if (new_catalog == (nl_catd) -1)
+ {
+ free (new_name);
+ return (char *) catalog_name;
+ }
+ }
+
+ /* Close old catalog. */
+ if (catalog != (nl_catd) -1)
+ catclose (catalog);
+ if (catalog_name != default_catalog_name)
+ free ((char *) catalog_name);
+
+ catalog = new_catalog;
+ catalog_name = new_name;
+
+ return (char *) catalog_name;
+}
+
+char *
+bindtextdomain (domainname, dirname)
+ const char *domainname;
+ const char *dirname;
+{
+#if HAVE_SETENV || HAVE_PUTENV
+ char *old_val, *new_val, *cp;
+ size_t new_val_len;
+
+ /* This does not make much sense here but to be compatible do it. */
+ if (domainname == NULL)
+ return NULL;
+
+ /* Compute length of added path element. If we use setenv we don't need
+ the first byts for NLSPATH=, but why complicate the code for this
+ peanuts. */
+ new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname)
+ + sizeof ("/%L/LC_MESSAGES/%N.cat");
+
+ old_val = getenv ("NLSPATH");
+ if (old_val == NULL || old_val[0] == '\0')
+ {
+ old_val = NULL;
+ new_val_len += 1 + sizeof (LOCALEDIR) - 1
+ + sizeof ("/%L/LC_MESSAGES/%N.cat");
+ }
+ else
+ new_val_len += strlen (old_val);
+
+ new_val = (char *) malloc (new_val_len);
+ if (new_val == NULL)
+ return NULL;
+
+# if HAVE_SETENV
+ cp = new_val;
+# else
+ cp = stpcpy (new_val, "NLSPATH=");
+# endif
+
+ cp = stpcpy (cp, dirname);
+ cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:");
+
+ if (old_val == NULL)
+ {
+# if __STDC__
+ stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat");
+# else
+
+ cp = stpcpy (cp, LOCALEDIR);
+ stpcpy (cp, "/%L/LC_MESSAGES/%N.cat");
+# endif
+ }
+ else
+ stpcpy (cp, old_val);
+
+# if HAVE_SETENV
+ setenv ("NLSPATH", new_val, 1);
+ free (new_val);
+# else
+ putenv (new_val);
+ /* Do *not* free the environment entry we just entered. It is used
+ from now on. */
+# endif
+
+#endif
+
+ return (char *) domainname;
+}
+
+#undef gettext
+char *
+gettext (msg)
+ const char *msg;
+{
+ int msgid;
+
+ if (msg == NULL || catalog == (nl_catd) -1)
+ return (char *) msg;
+
+ /* Get the message from the catalog. We always use set number 1.
+ The message ID is computed by the function `msg_to_cat_id'
+ which works on the table generated by `po-to-tbl'. */
+ msgid = msg_to_cat_id (msg);
+ if (msgid == -1)
+ return (char *) msg;
+
+ return catgets (catalog, 1, msgid, (char *) msg);
+}
+
+/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries
+ for the one equal to msg. If it is found return the ID. In case when
+ the string is not found return -1. */
+static int
+msg_to_cat_id (msg)
+ const char *msg;
+{
+ int cnt;
+
+ for (cnt = 0; cnt < _msg_tbl_length; ++cnt)
+ if (strcmp (msg, _msg_tbl[cnt]._msg) == 0)
+ return _msg_tbl[cnt]._msg_number;
+
+ return -1;
+}
+
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
diff --git a/current/intl/dcgettext.c b/current/intl/dcgettext.c
new file mode 100644
index 00000000..0f7bb486
--- /dev/null
+++ b/current/intl/dcgettext.c
@@ -0,0 +1,655 @@
+/* Implementation of the dcgettext(3) function.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#if defined __GNUC__ && !defined C_ALLOCA
+# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
+#else
+# if (defined HAVE_ALLOCA_H || defined _LIBC) && !defined C_ALLOCA
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+#ifndef __set_errno
+# define __set_errno(val) errno = (val)
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+char *getenv ();
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+# endif
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+#include "hash-string.h"
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define getcwd __getcwd
+# ifndef stpcpy
+# define stpcpy __stpcpy
+# endif
+#else
+# if !defined HAVE_GETCWD
+char *getwd ();
+# define getcwd(buf, max) getwd (buf)
+# else
+char *getcwd ();
+# endif
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
+#endif
+
+/* Amount to increase buffer size by in each try. */
+#define PATH_INCR 32
+
+/* The following is from pathmax.h. */
+/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
+ PATH_MAX but might cause redefinition warnings when sys/param.h is
+ later included (as on MORE/BSD 4.3). */
+#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
+# include <limits.h>
+#endif
+
+#ifndef _POSIX_PATH_MAX
+# define _POSIX_PATH_MAX 255
+#endif
+
+#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
+# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
+#endif
+
+/* Don't include sys/param.h if it already has been. */
+#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
+# include <sys/param.h>
+#endif
+
+#if !defined(PATH_MAX) && defined(MAXPATHLEN)
+# define PATH_MAX MAXPATHLEN
+#endif
+
+#ifndef PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+#endif
+
+/* XPG3 defines the result of `setlocale (category, NULL)' as:
+ ``Directs `setlocale()' to query `category' and return the current
+ setting of `local'.''
+ However it does not specify the exact format. And even worse: POSIX
+ defines this not at all. So we can use this feature only on selected
+ system (e.g. those using GNU C Library). */
+#ifdef _LIBC
+# define HAVE_LOCALE_NULL
+#endif
+
+/* Name of the default domain used for gettext(3) prior any call to
+ textdomain(3). The default value for this is "messages". */
+const char _nl_default_default_domain[] = "messages";
+
+/* Value used as the default domain for gettext(3). */
+const char *_nl_current_default_domain = _nl_default_default_domain;
+
+/* Contains the default location of the message catalogs. */
+const char _nl_default_dirname[] = GNULOCALEDIR;
+
+/* List with bindings of specific domains created by bindtextdomain()
+ calls. */
+struct binding *_nl_domain_bindings;
+
+/* Prototypes for local functions. */
+static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
+ const char *msgid)) internal_function;
+static const char *category_to_name PARAMS ((int category)) internal_function;
+static const char *guess_category_value PARAMS ((int category,
+ const char *categoryname))
+ internal_function;
+
+
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old); \
+ } \
+ } while (0)
+# undef alloca
+# define alloca(size) (malloc (size))
+#endif /* have alloca */
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define DCGETTEXT __dcgettext
+#else
+# define DCGETTEXT dcgettext__
+#endif
+
+/* Checking whether the binaries runs SUID must be done and glibc provides
+ easier methods therefore we make a difference here. */
+#ifdef _LIBC
+# define ENABLE_SECURE __libc_enable_secure
+# define DETERMINE_SECURE
+#else
+static int enable_secure;
+# define ENABLE_SECURE (enable_secure == 1)
+# define DETERMINE_SECURE \
+ if (enable_secure == 0) \
+ { \
+ if (getuid () != geteuid () || getgid () != getegid ()) \
+ enable_secure = 1; \
+ else \
+ enable_secure = -1; \
+ }
+#endif
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+ locale. */
+char *
+DCGETTEXT (domainname, msgid, category)
+ const char *domainname;
+ const char *msgid;
+ int category;
+{
+#ifndef HAVE_ALLOCA
+ struct block_list *block_list = NULL;
+#endif
+ struct loaded_l10nfile *domain;
+ struct binding *binding;
+ const char *categoryname;
+ const char *categoryvalue;
+ char *dirname, *xdomainname;
+ char *single_locale;
+ char *retval;
+ int saved_errno = errno;
+
+ /* If no real MSGID is given return NULL. */
+ if (msgid == NULL)
+ return NULL;
+
+ /* See whether this is a SUID binary or not. */
+ DETERMINE_SECURE;
+
+ /* If DOMAINNAME is NULL, we are interested in the default domain. If
+ CATEGORY is not LC_MESSAGES this might not make much sense but the
+ definition left this undefined. */
+ if (domainname == NULL)
+ domainname = _nl_current_default_domain;
+
+ /* First find matching binding. */
+ for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
+ {
+ int compare = strcmp (domainname, binding->domainname);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It is not in the list. */
+ binding = NULL;
+ break;
+ }
+ }
+
+ if (binding == NULL)
+ dirname = (char *) _nl_default_dirname;
+ else if (binding->dirname[0] == '/')
+ dirname = binding->dirname;
+ else
+ {
+ /* We have a relative path. Make it absolute now. */
+ size_t dirname_len = strlen (binding->dirname) + 1;
+ size_t path_max;
+ char *ret;
+
+ path_max = (unsigned int) PATH_MAX;
+ path_max += 2; /* The getcwd docs say to do this. */
+
+ dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
+
+ __set_errno (0);
+ while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
+ {
+ path_max += PATH_INCR;
+ dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
+ __set_errno (0);
+ }
+
+ if (ret == NULL)
+ {
+ /* We cannot get the current working directory. Don't signal an
+ error but simply return the default string. */
+ FREE_BLOCKS (block_list);
+ __set_errno (saved_errno);
+ return (char *) msgid;
+ }
+
+ stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
+ }
+
+ /* Now determine the symbolic name of CATEGORY and its value. */
+ categoryname = category_to_name (category);
+ categoryvalue = guess_category_value (category, categoryname);
+
+ xdomainname = (char *) alloca (strlen (categoryname)
+ + strlen (domainname) + 5);
+ ADD_BLOCK (block_list, xdomainname);
+
+ stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
+ domainname),
+ ".mo");
+
+ /* Creating working area. */
+ single_locale = (char *) alloca (strlen (categoryvalue) + 1);
+ ADD_BLOCK (block_list, single_locale);
+
+
+ /* Search for the given string. This is a loop because we perhaps
+ got an ordered list of languages to consider for the translation. */
+ while (1)
+ {
+ /* Make CATEGORYVALUE point to the next element of the list. */
+ while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
+ ++categoryvalue;
+ if (categoryvalue[0] == '\0')
+ {
+ /* The whole contents of CATEGORYVALUE has been searched but
+ no valid entry has been found. We solve this situation
+ by implicitly appending a "C" entry, i.e. no translation
+ will take place. */
+ single_locale[0] = 'C';
+ single_locale[1] = '\0';
+ }
+ else
+ {
+ char *cp = single_locale;
+ while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
+ *cp++ = *categoryvalue++;
+ *cp = '\0';
+
+ /* When this is a SUID binary we must not allow accessing files
+ outside the dedicated directories. */
+ if (ENABLE_SECURE
+ && (memchr (single_locale, '/',
+ _nl_find_language (single_locale) - single_locale)
+ != NULL))
+ /* Ingore this entry. */
+ continue;
+ }
+
+ /* If the current locale value is C (or POSIX) we don't load a
+ domain. Return the MSGID. */
+ if (strcmp (single_locale, "C") == 0
+ || strcmp (single_locale, "POSIX") == 0)
+ {
+ FREE_BLOCKS (block_list);
+ __set_errno (saved_errno);
+ return (char *) msgid;
+ }
+
+
+ /* Find structure describing the message catalog matching the
+ DOMAINNAME and CATEGORY. */
+ domain = _nl_find_domain (dirname, single_locale, xdomainname);
+
+ if (domain != NULL)
+ {
+ retval = find_msg (domain, msgid);
+
+ if (retval == NULL)
+ {
+ int cnt;
+
+ for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
+ {
+ retval = find_msg (domain->successor[cnt], msgid);
+
+ if (retval != NULL)
+ break;
+ }
+ }
+
+ if (retval != NULL)
+ {
+ FREE_BLOCKS (block_list);
+ __set_errno (saved_errno);
+ return retval;
+ }
+ }
+ }
+ /* NOTREACHED */
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__dcgettext, dcgettext);
+#endif
+
+
+static char *
+internal_function
+find_msg (domain_file, msgid)
+ struct loaded_l10nfile *domain_file;
+ const char *msgid;
+{
+ size_t act = 0;
+ size_t top, bottom;
+ struct loaded_domain *domain;
+
+ if (domain_file->decided == 0)
+ _nl_load_domain (domain_file);
+
+ if (domain_file->data == NULL)
+ return NULL;
+
+ domain = (struct loaded_domain *) domain_file->data;
+
+ /* Locate the MSGID and its translation. */
+ if (domain->hash_size > 2 && domain->hash_tab != NULL)
+ {
+ /* Use the hashing table. */
+ nls_uint32 len = strlen (msgid);
+ nls_uint32 hash_val = hash_string (msgid);
+ nls_uint32 idx = hash_val % domain->hash_size;
+ nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
+ nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
+
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
+ && strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset)) == 0)
+ return (char *) domain->data + W (domain->must_swap,
+ domain->trans_tab[nstr - 1].offset);
+
+ while (1)
+ {
+ if (idx >= domain->hash_size - incr)
+ idx -= domain->hash_size - incr;
+ else
+ idx += incr;
+
+ nstr = W (domain->must_swap, domain->hash_tab[idx]);
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
+ && strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset))
+ == 0)
+ return (char *) domain->data
+ + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
+ }
+ /* NOTREACHED */
+ }
+
+ /* Now we try the default method: binary search in the sorted
+ array of messages. */
+ bottom = 0;
+ top = domain->nstrings;
+ while (bottom < top)
+ {
+ int cmp_val;
+
+ act = (bottom + top) / 2;
+ cmp_val = strcmp (msgid, domain->data
+ + W (domain->must_swap,
+ domain->orig_tab[act].offset));
+ if (cmp_val < 0)
+ top = act;
+ else if (cmp_val > 0)
+ bottom = act + 1;
+ else
+ break;
+ }
+
+ /* If an translation is found return this. */
+ return bottom >= top ? NULL : (char *) domain->data
+ + W (domain->must_swap,
+ domain->trans_tab[act].offset);
+}
+
+
+/* Return string representation of locale CATEGORY. */
+static const char *
+internal_function
+category_to_name (category)
+ int category;
+{
+ const char *retval;
+
+ switch (category)
+ {
+#ifdef LC_COLLATE
+ case LC_COLLATE:
+ retval = "LC_COLLATE";
+ break;
+#endif
+#ifdef LC_CTYPE
+ case LC_CTYPE:
+ retval = "LC_CTYPE";
+ break;
+#endif
+#ifdef LC_MONETARY
+ case LC_MONETARY:
+ retval = "LC_MONETARY";
+ break;
+#endif
+#ifdef LC_NUMERIC
+ case LC_NUMERIC:
+ retval = "LC_NUMERIC";
+ break;
+#endif
+#ifdef LC_TIME
+ case LC_TIME:
+ retval = "LC_TIME";
+ break;
+#endif
+#ifdef LC_MESSAGES
+ case LC_MESSAGES:
+ retval = "LC_MESSAGES";
+ break;
+#endif
+#ifdef LC_RESPONSE
+ case LC_RESPONSE:
+ retval = "LC_RESPONSE";
+ break;
+#endif
+#ifdef LC_ALL
+ case LC_ALL:
+ /* This might not make sense but is perhaps better than any other
+ value. */
+ retval = "LC_ALL";
+ break;
+#endif
+ default:
+ /* If you have a better idea for a default value let me know. */
+ retval = "LC_XXX";
+ }
+
+ return retval;
+}
+
+/* Guess value of current locale from value of the environment variables. */
+static const char *
+internal_function
+guess_category_value (category, categoryname)
+ int category;
+ const char *categoryname;
+{
+ const char *retval;
+
+ /* The highest priority value is the `LANGUAGE' environment
+ variable. This is a GNU extension. */
+ retval = getenv ("LANGUAGE");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* `LANGUAGE' is not set. So we have to proceed with the POSIX
+ methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some
+ systems this can be done by the `setlocale' function itself. */
+#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
+ return setlocale (category, NULL);
+#else
+ /* Setting of LC_ALL overwrites all other. */
+ retval = getenv ("LC_ALL");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* Next comes the name of the desired category. */
+ retval = getenv (categoryname);
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* Last possibility is the LANG environment variable. */
+ retval = getenv ("LANG");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* We use C as the default domain. POSIX says this is implementation
+ defined. */
+ return "C";
+#endif
+}
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
+
+
+#ifdef _LIBC
+/* If we want to free all resources we have to do some work at
+ program's end. */
+static void __attribute__ ((unused))
+free_mem (void)
+{
+ struct binding *runp;
+
+ for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next)
+ {
+ free (runp->domainname);
+ if (runp->dirname != _nl_default_dirname)
+ /* Yes, this is a pointer comparison. */
+ free (runp->dirname);
+ }
+
+ if (_nl_current_default_domain != _nl_default_default_domain)
+ /* Yes, again a pointer comparison. */
+ free ((char *) _nl_current_default_domain);
+}
+
+text_set_element (__libc_subfreeres, free_mem);
+#endif
diff --git a/current/intl/dgettext.c b/current/intl/dgettext.c
new file mode 100644
index 00000000..0510c2b0
--- /dev/null
+++ b/current/intl/dgettext.c
@@ -0,0 +1,59 @@
+/* Implementation of the dgettext(3) function
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined HAVE_LOCALE_H || defined _LIBC
+# include <locale.h>
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define DGETTEXT __dgettext
+# define DCGETTEXT __dcgettext
+#else
+# define DGETTEXT dgettext__
+# define DCGETTEXT dcgettext__
+#endif
+
+/* Look up MSGID in the DOMAINNAME message catalog of the current
+ LC_MESSAGES locale. */
+char *
+DGETTEXT (domainname, msgid)
+ const char *domainname;
+ const char *msgid;
+{
+ return DCGETTEXT (domainname, msgid, LC_MESSAGES);
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__dgettext, dgettext);
+#endif
diff --git a/current/intl/explodename.c b/current/intl/explodename.c
new file mode 100644
index 00000000..80a3111c
--- /dev/null
+++ b/current/intl/explodename.c
@@ -0,0 +1,197 @@
+/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+#include <sys/types.h>
+
+#include "loadinfo.h"
+
+/* On some strange systems still no definition of NULL is found. Sigh! */
+#ifndef NULL
+# if defined __STDC__ && __STDC__
+# define NULL ((void *) 0)
+# else
+# define NULL 0
+# endif
+#endif
+
+/* @@ end of prolog @@ */
+
+char *
+_nl_find_language (const char *name)
+{
+ while (name[0] != '\0' && name[0] != '_' && name[0] != '@'
+ && name[0] != '+' && name[0] != ',')
+ ++name;
+
+ return (char *) name;
+}
+
+
+int
+_nl_explode_name (name, language, modifier, territory, codeset,
+ normalized_codeset, special, sponsor, revision)
+ char *name;
+ const char **language;
+ const char **modifier;
+ const char **territory;
+ const char **codeset;
+ const char **normalized_codeset;
+ const char **special;
+ const char **sponsor;
+ const char **revision;
+{
+ enum { undecided, xpg, cen } syntax;
+ char *cp;
+ int mask;
+
+ *modifier = NULL;
+ *territory = NULL;
+ *codeset = NULL;
+ *normalized_codeset = NULL;
+ *special = NULL;
+ *sponsor = NULL;
+ *revision = NULL;
+
+ /* Now we determine the single parts of the locale name. First
+ look for the language. Termination symbols are `_' and `@' if
+ we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
+ mask = 0;
+ syntax = undecided;
+ *language = cp = name;
+ cp = _nl_find_language (*language);
+
+ if (*language == cp)
+ /* This does not make sense: language has to be specified. Use
+ this entry as it is without exploding. Perhaps it is an alias. */
+ cp = strchr (*language, '\0');
+ else if (cp[0] == '_')
+ {
+ /* Next is the territory. */
+ cp[0] = '\0';
+ *territory = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
+ && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= TERRITORY;
+
+ if (cp[0] == '.')
+ {
+ /* Next is the codeset. */
+ syntax = xpg;
+ cp[0] = '\0';
+ *codeset = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '@')
+ ++cp;
+
+ mask |= XPG_CODESET;
+
+ if (*codeset != cp && (*codeset)[0] != '\0')
+ {
+ *normalized_codeset = _nl_normalize_codeset (*codeset,
+ cp - *codeset);
+ if (strcmp (*codeset, *normalized_codeset) == 0)
+ free ((char *) *normalized_codeset);
+ else
+ mask |= XPG_NORM_CODESET;
+ }
+ }
+ }
+
+ if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
+ {
+ /* Next is the modifier. */
+ syntax = cp[0] == '@' ? xpg : cen;
+ cp[0] = '\0';
+ *modifier = ++cp;
+
+ while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
+ && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= XPG_MODIFIER | CEN_AUDIENCE;
+ }
+
+ if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
+ {
+ syntax = cen;
+
+ if (cp[0] == '+')
+ {
+ /* Next is special application (CEN syntax). */
+ cp[0] = '\0';
+ *special = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= CEN_SPECIAL;
+ }
+
+ if (cp[0] == ',')
+ {
+ /* Next is sponsor (CEN syntax). */
+ cp[0] = '\0';
+ *sponsor = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '_')
+ ++cp;
+
+ mask |= CEN_SPONSOR;
+ }
+
+ if (cp[0] == '_')
+ {
+ /* Next is revision (CEN syntax). */
+ cp[0] = '\0';
+ *revision = ++cp;
+
+ mask |= CEN_REVISION;
+ }
+ }
+
+ /* For CEN syntax values it might be important to have the
+ separator character in the file name, not for XPG syntax. */
+ if (syntax == xpg)
+ {
+ if (*territory != NULL && (*territory)[0] == '\0')
+ mask &= ~TERRITORY;
+
+ if (*codeset != NULL && (*codeset)[0] == '\0')
+ mask &= ~XPG_CODESET;
+
+ if (*modifier != NULL && (*modifier)[0] == '\0')
+ mask &= ~XPG_MODIFIER;
+ }
+
+ return mask;
+}
diff --git a/current/intl/finddomain.c b/current/intl/finddomain.c
new file mode 100644
index 00000000..81ea29bf
--- /dev/null
+++ b/current/intl/finddomain.c
@@ -0,0 +1,216 @@
+/* Handle list of needed message catalogs
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+/* List of already loaded domains. */
+static struct loaded_l10nfile *_nl_loaded_domains;
+
+
+/* Return a data structure describing the message catalog described by
+ the DOMAINNAME and CATEGORY parameters with respect to the currently
+ established bindings. */
+struct loaded_l10nfile *
+internal_function
+_nl_find_domain (dirname, locale, domainname)
+ const char *dirname;
+ char *locale;
+ const char *domainname;
+{
+ struct loaded_l10nfile *retval;
+ const char *language;
+ const char *modifier;
+ const char *territory;
+ const char *codeset;
+ const char *normalized_codeset;
+ const char *special;
+ const char *sponsor;
+ const char *revision;
+ const char *alias_value;
+ int mask;
+
+ /* LOCALE can consist of up to four recognized parts for the XPG syntax:
+
+ language[_territory[.codeset]][@modifier]
+
+ and six parts for the CEN syntax:
+
+ language[_territory][+audience][+special][,[sponsor][_revision]]
+
+ Beside the first part all of them are allowed to be missing. If
+ the full specified locale is not found, the less specific one are
+ looked for. The various parts will be stripped off according to
+ the following order:
+ (1) revision
+ (2) sponsor
+ (3) special
+ (4) codeset
+ (5) normalized codeset
+ (6) territory
+ (7) audience/modifier
+ */
+
+ /* If we have already tested for this locale entry there has to
+ be one data set in the list of loaded domains. */
+ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ strlen (dirname) + 1, 0, locale, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, domainname, 0);
+ if (retval != NULL)
+ {
+ /* We know something about this locale. */
+ int cnt;
+
+ if (retval->decided == 0)
+ _nl_load_domain (retval);
+
+ if (retval->data != NULL)
+ return retval;
+
+ for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
+ {
+ if (retval->successor[cnt]->decided == 0)
+ _nl_load_domain (retval->successor[cnt]);
+
+ if (retval->successor[cnt]->data != NULL)
+ break;
+ }
+ return cnt >= 0 ? retval : NULL;
+ /* NOTREACHED */
+ }
+
+ /* See whether the locale value is an alias. If yes its value
+ *overwrites* the alias name. No test for the original value is
+ done. */
+ alias_value = _nl_expand_alias (locale);
+ if (alias_value != NULL)
+ {
+#if defined _LIBC || defined HAVE_STRDUP
+ locale = strdup (alias_value);
+ if (locale == NULL)
+ return NULL;
+#else
+ size_t len = strlen (alias_value) + 1;
+ locale = (char *) malloc (len);
+ if (locale == NULL)
+ return NULL;
+
+ memcpy (locale, alias_value, len);
+#endif
+ }
+
+ /* Now we determine the single parts of the locale name. First
+ look for the language. Termination symbols are `_' and `@' if
+ we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
+ mask = _nl_explode_name (locale, &language, &modifier, &territory,
+ &codeset, &normalized_codeset, &special,
+ &sponsor, &revision);
+
+ /* Create all possible locale entries which might be interested in
+ generalization. */
+ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ strlen (dirname) + 1, mask, language, territory,
+ codeset, normalized_codeset, modifier, special,
+ sponsor, revision, domainname, 1);
+ if (retval == NULL)
+ /* This means we are out of core. */
+ return NULL;
+
+ if (retval->decided == 0)
+ _nl_load_domain (retval);
+ if (retval->data == NULL)
+ {
+ int cnt;
+ for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
+ {
+ if (retval->successor[cnt]->decided == 0)
+ _nl_load_domain (retval->successor[cnt]);
+ if (retval->successor[cnt]->data != NULL)
+ break;
+ }
+ }
+
+ /* The room for an alias was dynamically allocated. Free it now. */
+ if (alias_value != NULL)
+ free (locale);
+
+ return retval;
+}
+
+
+#ifdef _LIBC
+static void __attribute__ ((unused))
+free_mem (void)
+{
+ struct loaded_l10nfile *runp = _nl_loaded_domains;
+
+ while (runp != NULL)
+ {
+ struct loaded_l10nfile *here = runp;
+ if (runp->data != NULL)
+ _nl_unload_domain ((struct loaded_domain *) runp->data);
+ runp = runp->next;
+ free (here);
+ }
+}
+
+text_set_element (__libc_subfreeres, free_mem);
+#endif
diff --git a/current/intl/gettext.c b/current/intl/gettext.c
new file mode 100644
index 00000000..d929f98d
--- /dev/null
+++ b/current/intl/gettext.c
@@ -0,0 +1,70 @@
+/* Implementation of gettext(3) function.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _LIBC
+# define __need_NULL
+# include <stddef.h>
+#else
+# ifdef STDC_HEADERS
+# include <stdlib.h> /* Just for NULL. */
+# else
+# ifdef HAVE_STRING_H
+# include <string.h>
+# else
+# define NULL ((void *) 0)
+# endif
+# endif
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define GETTEXT __gettext
+# define DGETTEXT __dgettext
+#else
+# define GETTEXT gettext__
+# define DGETTEXT dgettext__
+#endif
+
+/* Look up MSGID in the current default message catalog for the current
+ LC_MESSAGES locale. If not found, returns MSGID itself (the default
+ text). */
+char *
+GETTEXT (msgid)
+ const char *msgid;
+{
+ return DGETTEXT (NULL, msgid);
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__gettext, gettext);
+#endif
diff --git a/current/intl/gettext.h b/current/intl/gettext.h
new file mode 100644
index 00000000..3cd23d7d
--- /dev/null
+++ b/current/intl/gettext.h
@@ -0,0 +1,105 @@
+/* Internal header for GNU gettext internationalization functions.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _GETTEXT_H
+#define _GETTEXT_H 1
+
+#include <stdio.h>
+
+#if HAVE_LIMITS_H || _LIBC
+# include <limits.h>
+#endif
+
+/* @@ end of prolog @@ */
+
+/* The magic number of the GNU message catalog format. */
+#define _MAGIC 0x950412de
+#define _MAGIC_SWAPPED 0xde120495
+
+/* Revision number of the currently used .mo (binary) file format. */
+#define MO_REVISION_NUMBER 0
+
+/* The following contortions are an attempt to use the C preprocessor
+ to determine an unsigned integral type that is 32 bits wide. An
+ alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+ doing that would require that the configure script compile and *run*
+ the resulting executable. Locally running cross-compiled executables
+ is usually not possible. */
+
+#if __STDC__
+# define UINT_MAX_32_BITS 4294967295U
+#else
+# define UINT_MAX_32_BITS 0xFFFFFFFF
+#endif
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+ This should be valid for all systems GNU cares about because
+ that doesn't include 16-bit systems, and only modern systems
+ (that certainly have <limits.h>) have 64+-bit integral types. */
+
+#ifndef UINT_MAX
+# define UINT_MAX UINT_MAX_32_BITS
+#endif
+
+#if UINT_MAX == UINT_MAX_32_BITS
+typedef unsigned nls_uint32;
+#else
+# if USHRT_MAX == UINT_MAX_32_BITS
+typedef unsigned short nls_uint32;
+# else
+# if ULONG_MAX == UINT_MAX_32_BITS
+typedef unsigned long nls_uint32;
+# else
+ /* The following line is intended to throw an error. Using #error is
+ not portable enough. */
+ "Cannot determine unsigned 32-bit data type."
+# endif
+# endif
+#endif
+
+
+/* Header for binary .mo file format. */
+struct mo_file_header
+{
+ /* The magic number. */
+ nls_uint32 magic;
+ /* The revision number of the file format. */
+ nls_uint32 revision;
+ /* The number of strings pairs. */
+ nls_uint32 nstrings;
+ /* Offset of table with start offsets of original strings. */
+ nls_uint32 orig_tab_offset;
+ /* Offset of table with start offsets of translation strings. */
+ nls_uint32 trans_tab_offset;
+ /* Size of hashing table. */
+ nls_uint32 hash_tab_size;
+ /* Offset of first hashing entry. */
+ nls_uint32 hash_tab_offset;
+};
+
+struct string_desc
+{
+ /* Length of addressed string. */
+ nls_uint32 length;
+ /* Offset of string in file. */
+ nls_uint32 offset;
+};
+
+/* @@ begin of epilog @@ */
+
+#endif /* gettext.h */
diff --git a/current/intl/gettextP.h b/current/intl/gettextP.h
new file mode 100644
index 00000000..00c52031
--- /dev/null
+++ b/current/intl/gettextP.h
@@ -0,0 +1,89 @@
+/* Header describing internals of gettext library
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _GETTEXTP_H
+#define _GETTEXTP_H
+
+#include "loadinfo.h"
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+#ifndef internal_function
+# define internal_function
+#endif
+
+#ifndef W
+# define W(flag, data) ((flag) ? SWAP (data) : (data))
+#endif
+
+
+#ifdef _LIBC
+# include <byteswap.h>
+# define SWAP(i) bswap_32 (i)
+#else
+static nls_uint32 SWAP PARAMS ((nls_uint32 i));
+
+static inline nls_uint32
+SWAP (i)
+ nls_uint32 i;
+{
+ return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
+}
+#endif
+
+
+struct loaded_domain
+{
+ const char *data;
+ int use_mmap;
+ size_t mmap_size;
+ int must_swap;
+ nls_uint32 nstrings;
+ struct string_desc *orig_tab;
+ struct string_desc *trans_tab;
+ nls_uint32 hash_size;
+ nls_uint32 *hash_tab;
+};
+
+struct binding
+{
+ struct binding *next;
+ char *domainname;
+ char *dirname;
+};
+
+struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
+ char *__locale,
+ const char *__domainname))
+ internal_function;
+void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain))
+ internal_function;
+void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
+ internal_function;
+
+/* @@ begin of epilog @@ */
+
+#endif /* gettextP.h */
diff --git a/current/intl/hash-string.h b/current/intl/hash-string.h
new file mode 100644
index 00000000..939e9582
--- /dev/null
+++ b/current/intl/hash-string.h
@@ -0,0 +1,59 @@
+/* Implements a string hashing function.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(Args) Args
+# else
+# define PARAMS(Args) ()
+# endif
+#endif
+
+/* We assume to have `unsigned long int' value with at least 32 bits. */
+#define HASHWORDBITS 32
+
+
+/* Defines the so called `hashpjw' function by P.J. Weinberger
+ [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+ 1986, 1987 Bell Telephone Laboratories, Inc.] */
+static unsigned long int hash_string PARAMS ((const char *__str_param));
+
+static inline unsigned long int
+hash_string (str_param)
+ const char *str_param;
+{
+ unsigned long int hval, g;
+ const char *str = str_param;
+
+ /* Compute the hash value for the given string. */
+ hval = 0;
+ while (*str != '\0')
+ {
+ hval <<= 4;
+ hval += (unsigned long int) *str++;
+ g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
+ if (g != 0)
+ {
+ hval ^= g >> (HASHWORDBITS - 8);
+ hval ^= g;
+ }
+ }
+ return hval;
+}
diff --git a/current/intl/intl-compat.c b/current/intl/intl-compat.c
new file mode 100644
index 00000000..503efa0f
--- /dev/null
+++ b/current/intl/intl-compat.c
@@ -0,0 +1,76 @@
+/* intl-compat.c - Stub functions to call gettext functions from GNU gettext
+ Library.
+ Copyright (C) 1995 Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libgettext.h"
+
+/* @@ end of prolog @@ */
+
+
+#undef gettext
+#undef dgettext
+#undef dcgettext
+#undef textdomain
+#undef bindtextdomain
+
+
+char *
+bindtextdomain (domainname, dirname)
+ const char *domainname;
+ const char *dirname;
+{
+ return bindtextdomain__ (domainname, dirname);
+}
+
+
+char *
+dcgettext (domainname, msgid, category)
+ const char *domainname;
+ const char *msgid;
+ int category;
+{
+ return dcgettext__ (domainname, msgid, category);
+}
+
+
+char *
+dgettext (domainname, msgid)
+ const char *domainname;
+ const char *msgid;
+{
+ return dgettext__ (domainname, msgid);
+}
+
+
+char *
+gettext (msgid)
+ const char *msgid;
+{
+ return gettext__ (msgid);
+}
+
+
+char *
+textdomain (domainname)
+ const char *domainname;
+{
+ return textdomain__ (domainname);
+}
diff --git a/current/intl/l10nflist.c b/current/intl/l10nflist.c
new file mode 100644
index 00000000..30f5f645
--- /dev/null
+++ b/current/intl/l10nflist.c
@@ -0,0 +1,411 @@
+/* Handle list of needed message catalogs
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#if defined HAVE_STRING_H || defined _LIBC
+# ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+# endif
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#if defined _LIBC || defined HAVE_ARGZ_H
+# include <argz.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#include "loadinfo.h"
+
+/* On some strange systems still no definition of NULL is found. Sigh! */
+#ifndef NULL
+# if defined __STDC__ && __STDC__
+# define NULL ((void *) 0)
+# else
+# define NULL 0
+# endif
+#endif
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# ifndef stpcpy
+# define stpcpy(dest, src) __stpcpy(dest, src)
+# endif
+#else
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
+#endif
+
+/* Define function which are usually not available. */
+
+#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
+/* Returns the number of strings in ARGZ. */
+static size_t argz_count__ PARAMS ((const char *argz, size_t len));
+
+static size_t
+argz_count__ (argz, len)
+ const char *argz;
+ size_t len;
+{
+ size_t count = 0;
+ while (len > 0)
+ {
+ size_t part_len = strlen (argz);
+ argz += part_len + 1;
+ len -= part_len + 1;
+ count++;
+ }
+ return count;
+}
+# undef __argz_count
+# define __argz_count(argz, len) argz_count__ (argz, len)
+#endif /* !_LIBC && !HAVE___ARGZ_COUNT */
+
+#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
+/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+ except the last into the character SEP. */
+static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
+
+static void
+argz_stringify__ (argz, len, sep)
+ char *argz;
+ size_t len;
+ int sep;
+{
+ while (len > 0)
+ {
+ size_t part_len = strlen (argz);
+ argz += part_len;
+ len -= part_len + 1;
+ if (len > 0)
+ *argz++ = sep;
+ }
+}
+# undef __argz_stringify
+# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
+#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */
+
+#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
+static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
+ const char *entry));
+
+static char *
+argz_next__ (argz, argz_len, entry)
+ char *argz;
+ size_t argz_len;
+ const char *entry;
+{
+ if (entry)
+ {
+ if (entry < argz + argz_len)
+ entry = strchr (entry, '\0') + 1;
+
+ return entry >= argz + argz_len ? NULL : (char *) entry;
+ }
+ else
+ if (argz_len > 0)
+ return argz;
+ else
+ return 0;
+}
+# undef __argz_next
+# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
+#endif /* !_LIBC && !HAVE___ARGZ_NEXT */
+
+
+/* Return number of bits set in X. */
+static int pop PARAMS ((int x));
+
+static inline int
+pop (x)
+ int x;
+{
+ /* We assume that no more than 16 bits are used. */
+ x = ((x & ~0x5555) >> 1) + (x & 0x5555);
+ x = ((x & ~0x3333) >> 2) + (x & 0x3333);
+ x = ((x >> 4) + x) & 0x0f0f;
+ x = ((x >> 8) + x) & 0xff;
+
+ return x;
+}
+
+
+struct loaded_l10nfile *
+_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
+ territory, codeset, normalized_codeset, modifier, special,
+ sponsor, revision, filename, do_allocate)
+ struct loaded_l10nfile **l10nfile_list;
+ const char *dirlist;
+ size_t dirlist_len;
+ int mask;
+ const char *language;
+ const char *territory;
+ const char *codeset;
+ const char *normalized_codeset;
+ const char *modifier;
+ const char *special;
+ const char *sponsor;
+ const char *revision;
+ const char *filename;
+ int do_allocate;
+{
+ char *abs_filename;
+ struct loaded_l10nfile *last = NULL;
+ struct loaded_l10nfile *retval;
+ char *cp;
+ size_t entries;
+ int cnt;
+
+ /* Allocate room for the full file name. */
+ abs_filename = (char *) malloc (dirlist_len
+ + strlen (language)
+ + ((mask & TERRITORY) != 0
+ ? strlen (territory) + 1 : 0)
+ + ((mask & XPG_CODESET) != 0
+ ? strlen (codeset) + 1 : 0)
+ + ((mask & XPG_NORM_CODESET) != 0
+ ? strlen (normalized_codeset) + 1 : 0)
+ + (((mask & XPG_MODIFIER) != 0
+ || (mask & CEN_AUDIENCE) != 0)
+ ? strlen (modifier) + 1 : 0)
+ + ((mask & CEN_SPECIAL) != 0
+ ? strlen (special) + 1 : 0)
+ + (((mask & CEN_SPONSOR) != 0
+ || (mask & CEN_REVISION) != 0)
+ ? (1 + ((mask & CEN_SPONSOR) != 0
+ ? strlen (sponsor) + 1 : 0)
+ + ((mask & CEN_REVISION) != 0
+ ? strlen (revision) + 1 : 0)) : 0)
+ + 1 + strlen (filename) + 1);
+
+ if (abs_filename == NULL)
+ return NULL;
+
+ retval = NULL;
+ last = NULL;
+
+ /* Construct file name. */
+ memcpy (abs_filename, dirlist, dirlist_len);
+ __argz_stringify (abs_filename, dirlist_len, ':');
+ cp = abs_filename + (dirlist_len - 1);
+ *cp++ = '/';
+ cp = stpcpy (cp, language);
+
+ if ((mask & TERRITORY) != 0)
+ {
+ *cp++ = '_';
+ cp = stpcpy (cp, territory);
+ }
+ if ((mask & XPG_CODESET) != 0)
+ {
+ *cp++ = '.';
+ cp = stpcpy (cp, codeset);
+ }
+ if ((mask & XPG_NORM_CODESET) != 0)
+ {
+ *cp++ = '.';
+ cp = stpcpy (cp, normalized_codeset);
+ }
+ if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
+ {
+ /* This component can be part of both syntaces but has different
+ leading characters. For CEN we use `+', else `@'. */
+ *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
+ cp = stpcpy (cp, modifier);
+ }
+ if ((mask & CEN_SPECIAL) != 0)
+ {
+ *cp++ = '+';
+ cp = stpcpy (cp, special);
+ }
+ if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
+ {
+ *cp++ = ',';
+ if ((mask & CEN_SPONSOR) != 0)
+ cp = stpcpy (cp, sponsor);
+ if ((mask & CEN_REVISION) != 0)
+ {
+ *cp++ = '_';
+ cp = stpcpy (cp, revision);
+ }
+ }
+
+ *cp++ = '/';
+ stpcpy (cp, filename);
+
+ /* Look in list of already loaded domains whether it is already
+ available. */
+ last = NULL;
+ for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
+ if (retval->filename != NULL)
+ {
+ int compare = strcmp (retval->filename, abs_filename);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It's not in the list. */
+ retval = NULL;
+ break;
+ }
+
+ last = retval;
+ }
+
+ if (retval != NULL || do_allocate == 0)
+ {
+ free (abs_filename);
+ return retval;
+ }
+
+ retval = (struct loaded_l10nfile *)
+ malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
+ * (1 << pop (mask))
+ * sizeof (struct loaded_l10nfile *)));
+ if (retval == NULL)
+ return NULL;
+
+ retval->filename = abs_filename;
+ retval->decided = (__argz_count (dirlist, dirlist_len) != 1
+ || ((mask & XPG_CODESET) != 0
+ && (mask & XPG_NORM_CODESET) != 0));
+ retval->data = NULL;
+
+ if (last == NULL)
+ {
+ retval->next = *l10nfile_list;
+ *l10nfile_list = retval;
+ }
+ else
+ {
+ retval->next = last->next;
+ last->next = retval;
+ }
+
+ entries = 0;
+ /* If the DIRLIST is a real list the RETVAL entry corresponds not to
+ a real file. So we have to use the DIRLIST separation mechanism
+ of the inner loop. */
+ cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
+ for (; cnt >= 0; --cnt)
+ if ((cnt & ~mask) == 0
+ && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
+ && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
+ {
+ /* Iterate over all elements of the DIRLIST. */
+ char *dir = NULL;
+
+ while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
+ != NULL)
+ retval->successor[entries++]
+ = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
+ language, territory, codeset,
+ normalized_codeset, modifier, special,
+ sponsor, revision, filename, 1);
+ }
+ retval->successor[entries] = NULL;
+
+ return retval;
+}
+
+/* Normalize codeset name. There is no standard for the codeset
+ names. Normalization allows the user to use any of the common
+ names. */
+const char *
+_nl_normalize_codeset (codeset, name_len)
+ const char *codeset;
+ size_t name_len;
+{
+ int len = 0;
+ int only_digit = 1;
+ char *retval;
+ char *wp;
+ size_t cnt;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalnum (codeset[cnt]))
+ {
+ ++len;
+
+ if (isalpha (codeset[cnt]))
+ only_digit = 0;
+ }
+
+ retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
+
+ if (retval != NULL)
+ {
+ if (only_digit)
+ wp = stpcpy (retval, "iso");
+ else
+ wp = retval;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalpha (codeset[cnt]))
+ *wp++ = tolower (codeset[cnt]);
+ else if (isdigit (codeset[cnt]))
+ *wp++ = codeset[cnt];
+
+ *wp = '\0';
+ }
+
+ return (const char *) retval;
+}
+
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
diff --git a/current/intl/libgettext.h b/current/intl/libgettext.h
new file mode 100644
index 00000000..3a92960a
--- /dev/null
+++ b/current/intl/libgettext.h
@@ -0,0 +1,182 @@
+/* Message catalogs for internationalization.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Because on some systems (e.g. Solaris) we sometimes have to include
+ the systems libintl.h as well as this file we have more complex
+ include protection above. But the systems header might perhaps also
+ define _LIBINTL_H and therefore we have to protect the definition here. */
+
+#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H
+#ifndef _LIBINTL_H
+# define _LIBINTL_H 1
+#endif
+#define _LIBGETTEXT_H 1
+
+/* We define an additional symbol to signal that we use the GNU
+ implementation of gettext. */
+#define __USE_GNU_GETTEXT 1
+
+#include <sys/types.h>
+
+#if HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__ || defined __cplusplus
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+#ifndef NULL
+# if !defined __cplusplus || defined __GNUC__
+# define NULL ((void *) 0)
+# else
+# define NULL (0)
+# endif
+#endif
+
+#if !HAVE_LC_MESSAGES
+/* This value determines the behaviour of the gettext() and dgettext()
+ function. But some system does not have this defined. Define it
+ to a default value. */
+# define LC_MESSAGES (-1)
+#endif
+
+
+/* Declarations for gettext-using-catgets interface. Derived from
+ Jim Meyering's libintl.h. */
+struct _msg_ent
+{
+ const char *_msg;
+ int _msg_number;
+};
+
+
+#if HAVE_CATGETS
+/* These two variables are defined in the automatically by po-to-tbl.sed
+ generated file `cat-id-tbl.c'. */
+extern const struct _msg_ent _msg_tbl[];
+extern int _msg_tbl_length;
+#endif
+
+
+/* For automatical extraction of messages sometimes no real
+ translation is needed. Instead the string itself is the result. */
+#define gettext_noop(Str) (Str)
+
+/* Look up MSGID in the current default message catalog for the current
+ LC_MESSAGES locale. If not found, returns MSGID itself (the default
+ text). */
+extern char *gettext PARAMS ((const char *__msgid));
+extern char *gettext__ PARAMS ((const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current
+ LC_MESSAGES locale. */
+extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid));
+extern char *dgettext__ PARAMS ((const char *__domainname,
+ const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+ locale. */
+extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid,
+ int __category));
+extern char *dcgettext__ PARAMS ((const char *__domainname,
+ const char *__msgid, int __category));
+
+
+/* Set the current default message catalog to DOMAINNAME.
+ If DOMAINNAME is null, return the current default.
+ If DOMAINNAME is "", reset to the default of "messages". */
+extern char *textdomain PARAMS ((const char *__domainname));
+extern char *textdomain__ PARAMS ((const char *__domainname));
+
+/* Specify that the DOMAINNAME message catalog will be found
+ in DIRNAME rather than in the system locale data base. */
+extern char *bindtextdomain PARAMS ((const char *__domainname,
+ const char *__dirname));
+extern char *bindtextdomain__ PARAMS ((const char *__domainname,
+ const char *__dirname));
+
+#if ENABLE_NLS
+
+/* Solaris 2.3 has the gettext function but dcgettext is missing.
+ So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4
+ has dcgettext. */
+# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT)
+
+# define gettext(Msgid) \
+ dgettext (NULL, Msgid)
+
+# define dgettext(Domainname, Msgid) \
+ dcgettext (Domainname, Msgid, LC_MESSAGES)
+
+# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+/* This global variable is defined in loadmsgcat.c. We need a sign,
+ whether a new catalog was loaded, which can be associated with all
+ translations. */
+extern int _nl_msg_cat_cntr;
+
+# define dcgettext(Domainname, Msgid, Category) \
+ (__extension__ \
+ ({ \
+ char *__result; \
+ if (__builtin_constant_p (Msgid)) \
+ { \
+ static char *__translation__; \
+ static int __catalog_counter__; \
+ if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
+ { \
+ __translation__ = \
+ dcgettext__ (Domainname, Msgid, Category); \
+ __catalog_counter__ = _nl_msg_cat_cntr; \
+ } \
+ __result = __translation__; \
+ } \
+ else \
+ __result = dcgettext__ (Domainname, Msgid, Category); \
+ __result; \
+ }))
+# endif
+# endif
+
+#else
+
+# define gettext(Msgid) (Msgid)
+# define dgettext(Domainname, Msgid) (Msgid)
+# define dcgettext(Domainname, Msgid, Category) (Msgid)
+# define textdomain(Domainname) ((char *) Domainname)
+# define bindtextdomain(Domainname, Dirname) ((char *) Dirname)
+
+#endif
+
+/* @@ begin of epilog @@ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/current/intl/linux-msg.sed b/current/intl/linux-msg.sed
new file mode 100644
index 00000000..5918e720
--- /dev/null
+++ b/current/intl/linux-msg.sed
@@ -0,0 +1,100 @@
+# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+# The first directive in the .msg should be the definition of the
+# message set number. We use always set number 1.
+#
+1 {
+ i\
+$set 1 # Automatically created by po2msg.sed
+ h
+ s/.*/0/
+ x
+}
+#
+# Mitch's old catalog format does not allow comments.
+#
+# We copy the original message as a comment into the .msg file.
+#
+/^msgid/ {
+ s/msgid[ ]*"//
+#
+# This does not work now with the new format.
+# /"$/! {
+# s/\\$//
+# s/$/ ... (more lines following)"/
+# }
+ x
+# The following nice solution is by
+# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
+ td
+# Increment a decimal number in pattern space.
+# First hide trailing `9' digits.
+ :d
+ s/9\(_*\)$/_\1/
+ td
+# Assure at least one digit is available.
+ s/^\(_*\)$/0\1/
+# Increment the last digit.
+ s/8\(_*\)$/9\1/
+ s/7\(_*\)$/8\1/
+ s/6\(_*\)$/7\1/
+ s/5\(_*\)$/6\1/
+ s/4\(_*\)$/5\1/
+ s/3\(_*\)$/4\1/
+ s/2\(_*\)$/3\1/
+ s/1\(_*\)$/2\1/
+ s/0\(_*\)$/1\1/
+# Convert the hidden `9' digits to `0's.
+ s/_/0/g
+ x
+ G
+ s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p
+}
+#
+# The .msg file contains, other then the .po file, only the translations
+# but each given a unique ID. Starting from 1 and incrementing by 1 for
+# each message we assign them to the messages.
+# It is important that the .po file used to generate the cat-id-tbl.c file
+# (with po-to-tbl) is the same as the one used here. (At least the order
+# of declarations must not be changed.)
+#
+/^msgstr/ {
+ s/msgstr[ ]*"\(.*\)"/# \1/
+# Clear substitution flag.
+ tb
+# Append the next line.
+ :b
+ N
+# Look whether second part is continuation line.
+ s/\(.*\n\)"\(.*\)"/\1\2/
+# Yes, then branch.
+ ta
+ P
+ D
+# Note that D includes a jump to the start!!
+# We found a continuation line. But before printing insert '\'.
+ :a
+ s/\(.*\)\(\n.*\)/\1\\\2/
+ P
+# We cannot use D here.
+ s/.*\n\(.*\)/\1/
+ tb
+}
+d
diff --git a/current/intl/loadinfo.h b/current/intl/loadinfo.h
new file mode 100644
index 00000000..1c4524ab
--- /dev/null
+++ b/current/intl/loadinfo.h
@@ -0,0 +1,78 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+/* Encoding of locale name parts. */
+#define CEN_REVISION 1
+#define CEN_SPONSOR 2
+#define CEN_SPECIAL 4
+#define XPG_NORM_CODESET 8
+#define XPG_CODESET 16
+#define TERRITORY 32
+#define CEN_AUDIENCE 64
+#define XPG_MODIFIER 128
+
+#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
+#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
+
+
+struct loaded_l10nfile
+{
+ const char *filename;
+ int decided;
+
+ const void *data;
+
+ struct loaded_l10nfile *next;
+ struct loaded_l10nfile *successor[1];
+};
+
+
+extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
+ size_t name_len));
+
+extern struct loaded_l10nfile *
+_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list,
+ const char *dirlist, size_t dirlist_len, int mask,
+ const char *language, const char *territory,
+ const char *codeset,
+ const char *normalized_codeset,
+ const char *modifier, const char *special,
+ const char *sponsor, const char *revision,
+ const char *filename, int do_allocate));
+
+
+extern const char *_nl_expand_alias PARAMS ((const char *name));
+
+extern int _nl_explode_name PARAMS ((char *name, const char **language,
+ const char **modifier,
+ const char **territory,
+ const char **codeset,
+ const char **normalized_codeset,
+ const char **special,
+ const char **sponsor,
+ const char **revision));
+
+extern char *_nl_find_language PARAMS ((const char *name));
diff --git a/current/intl/loadmsgcat.c b/current/intl/loadmsgcat.c
new file mode 100644
index 00000000..2c6a5650
--- /dev/null
+++ b/current/intl/loadmsgcat.c
@@ -0,0 +1,220 @@
+/* Load needed message catalogs.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+ || (defined _LIBC && defined _POSIX_MAPPED_FILES)
+# include <sys/mman.h>
+# undef HAVE_MMAP
+# define HAVE_MMAP 1
+#else
+# undef HAVE_MMAP
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ISO C functions. This is required by the standard
+ because some ISO C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define open __open
+# define close __close
+# define read __read
+# define mmap __mmap
+# define munmap __munmap
+#endif
+
+/* We need a sign, whether a new catalog was loaded, which can be associated
+ with all translations. This is important if the translations are
+ cached by one of GCC's features. */
+int _nl_msg_cat_cntr = 0;
+
+
+/* Load the message catalogs specified by FILENAME. If it is no valid
+ message catalog do nothing. */
+void
+internal_function
+_nl_load_domain (domain_file)
+ struct loaded_l10nfile *domain_file;
+{
+ int fd;
+ size_t size;
+ struct stat st;
+ struct mo_file_header *data = (struct mo_file_header *) -1;
+ int use_mmap = 0;
+ struct loaded_domain *domain;
+
+ domain_file->decided = 1;
+ domain_file->data = NULL;
+
+ /* If the record does not represent a valid locale the FILENAME
+ might be NULL. This can happen when according to the given
+ specification the locale file name is different for XPG and CEN
+ syntax. */
+ if (domain_file->filename == NULL)
+ return;
+
+ /* Try to open the addressed file. */
+ fd = open (domain_file->filename, O_RDONLY);
+ if (fd == -1)
+ return;
+
+ /* We must know about the size of the file. */
+ if (fstat (fd, &st) != 0
+ || (size = (size_t) st.st_size) != st.st_size
+ || size < sizeof (struct mo_file_header))
+ {
+ /* Something went wrong. */
+ close (fd);
+ return;
+ }
+
+#ifdef HAVE_MMAP
+ /* Now we are ready to load the file. If mmap() is available we try
+ this first. If not available or it failed we try to load it. */
+ data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
+ MAP_PRIVATE, fd, 0);
+
+ if (data != (struct mo_file_header *) -1)
+ {
+ /* mmap() call was successful. */
+ close (fd);
+ use_mmap = 1;
+ }
+#endif
+
+ /* If the data is not yet available (i.e. mmap'ed) we try to load
+ it manually. */
+ if (data == (struct mo_file_header *) -1)
+ {
+ size_t to_read;
+ char *read_ptr;
+
+ data = (struct mo_file_header *) malloc (size);
+ if (data == NULL)
+ return;
+
+ to_read = size;
+ read_ptr = (char *) data;
+ do
+ {
+ long int nb = (long int) read (fd, read_ptr, to_read);
+ if (nb == -1)
+ {
+ close (fd);
+ return;
+ }
+
+ read_ptr += nb;
+ to_read -= nb;
+ }
+ while (to_read > 0);
+
+ close (fd);
+ }
+
+ /* Using the magic number we can test whether it really is a message
+ catalog file. */
+ if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
+ {
+ /* The magic number is wrong: not a message catalog file. */
+#ifdef HAVE_MMAP
+ if (use_mmap)
+ munmap ((caddr_t) data, size);
+ else
+#endif
+ free (data);
+ return;
+ }
+
+ domain_file->data
+ = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
+ if (domain_file->data == NULL)
+ return;
+
+ domain = (struct loaded_domain *) domain_file->data;
+ domain->data = (char *) data;
+ domain->use_mmap = use_mmap;
+ domain->mmap_size = size;
+ domain->must_swap = data->magic != _MAGIC;
+
+ /* Fill in the information about the available tables. */
+ switch (W (domain->must_swap, data->revision))
+ {
+ case 0:
+ domain->nstrings = W (domain->must_swap, data->nstrings);
+ domain->orig_tab = (struct string_desc *)
+ ((char *) data + W (domain->must_swap, data->orig_tab_offset));
+ domain->trans_tab = (struct string_desc *)
+ ((char *) data + W (domain->must_swap, data->trans_tab_offset));
+ domain->hash_size = W (domain->must_swap, data->hash_tab_size);
+ domain->hash_tab = (nls_uint32 *)
+ ((char *) data + W (domain->must_swap, data->hash_tab_offset));
+ break;
+ default:
+ /* This is an invalid revision. */
+#ifdef HAVE_MMAP
+ if (use_mmap)
+ munmap ((caddr_t) data, size);
+ else
+#endif
+ free (data);
+ free (domain);
+ domain_file->data = NULL;
+ return;
+ }
+
+ /* Show that one domain is changed. This might make some cached
+ translations invalid. */
+ ++_nl_msg_cat_cntr;
+}
+
+
+#ifdef _LIBC
+void
+internal_function
+_nl_unload_domain (domain)
+ struct loaded_domain *domain;
+{
+#ifdef _POSIX_MAPPED_FILES
+ if (domain->use_mmap)
+ munmap ((caddr_t) domain->data, domain->mmap_size);
+ else
+#endif /* _POSIX_MAPPED_FILES */
+ free ((void *) domain->data);
+
+ free (domain);
+}
+#endif
diff --git a/current/intl/localealias.c b/current/intl/localealias.c
new file mode 100644
index 00000000..861020dd
--- /dev/null
+++ b/current/intl/localealias.c
@@ -0,0 +1,438 @@
+/* Handle aliases for locale names.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
+#else
+# if defined HAVE_ALLOCA_H || defined _LIBC
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+char *getenv ();
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+# endif
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define strcasecmp __strcasecmp
+
+# ifndef mempcpy
+# define mempcpy __mempcpy
+# endif
+# define HAVE_MEMPCPY 1
+
+/* We need locking here since we can be called from different places. */
+# include <bits/libc-lock.h>
+
+__libc_lock_define_initialized (static, lock);
+#endif
+
+#ifndef internal_function
+# define internal_function
+#endif
+
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old); \
+ } \
+ } while (0)
+# undef alloca
+# define alloca(size) (malloc (size))
+#endif /* have alloca */
+
+#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
+# undef fgets
+# define fgets(buf, len, s) fgets_unlocked (buf, len, s)
+#endif
+#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED
+# undef feof
+# define feof(s) feof_unlocked (s)
+#endif
+
+
+struct alias_map
+{
+ const char *alias;
+ const char *value;
+};
+
+
+static char *string_space = NULL;
+static size_t string_space_act = 0;
+static size_t string_space_max = 0;
+static struct alias_map *map;
+static size_t nmap = 0;
+static size_t maxmap = 0;
+
+
+/* Prototypes for local functions. */
+static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
+ internal_function;
+static void extend_alias_table PARAMS ((void));
+static int alias_compare PARAMS ((const struct alias_map *map1,
+ const struct alias_map *map2));
+
+
+const char *
+_nl_expand_alias (name)
+ const char *name;
+{
+ static const char *locale_alias_path = LOCALE_ALIAS_PATH;
+ struct alias_map *retval;
+ const char *result = NULL;
+ size_t added;
+
+#ifdef _LIBC
+ __libc_lock_lock (lock);
+#endif
+
+ do
+ {
+ struct alias_map item;
+
+ item.alias = name;
+
+ if (nmap > 0)
+ retval = (struct alias_map *) bsearch (&item, map, nmap,
+ sizeof (struct alias_map),
+ (int (*) PARAMS ((const void *,
+ const void *))
+ ) alias_compare);
+ else
+ retval = NULL;
+
+ /* We really found an alias. Return the value. */
+ if (retval != NULL)
+ {
+ result = retval->value;
+ break;
+ }
+
+ /* Perhaps we can find another alias file. */
+ added = 0;
+ while (added == 0 && locale_alias_path[0] != '\0')
+ {
+ const char *start;
+
+ while (locale_alias_path[0] == ':')
+ ++locale_alias_path;
+ start = locale_alias_path;
+
+ while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
+ ++locale_alias_path;
+
+ if (start < locale_alias_path)
+ added = read_alias_file (start, locale_alias_path - start);
+ }
+ }
+ while (added != 0);
+
+#ifdef _LIBC
+ __libc_lock_unlock (lock);
+#endif
+
+ return result;
+}
+
+
+static size_t
+internal_function
+read_alias_file (fname, fname_len)
+ const char *fname;
+ int fname_len;
+{
+#ifndef HAVE_ALLOCA
+ struct block_list *block_list = NULL;
+#endif
+ FILE *fp;
+ char *full_fname;
+ size_t added;
+ static const char aliasfile[] = "/locale.alias";
+
+ full_fname = (char *) alloca (fname_len + sizeof aliasfile);
+ ADD_BLOCK (block_list, full_fname);
+#ifdef HAVE_MEMPCPY
+ mempcpy (mempcpy (full_fname, fname, fname_len),
+ aliasfile, sizeof aliasfile);
+#else
+ memcpy (full_fname, fname, fname_len);
+ memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
+#endif
+
+ fp = fopen (full_fname, "r");
+ if (fp == NULL)
+ {
+ FREE_BLOCKS (block_list);
+ return 0;
+ }
+
+ added = 0;
+ while (!feof (fp))
+ {
+ /* It is a reasonable approach to use a fix buffer here because
+ a) we are only interested in the first two fields
+ b) these fields must be usable as file names and so must not
+ be that long
+ */
+ char buf[BUFSIZ];
+ char *alias;
+ char *value;
+ char *cp;
+
+ if (fgets (buf, sizeof buf, fp) == NULL)
+ /* EOF reached. */
+ break;
+
+ /* Possibly not the whole line fits into the buffer. Ignore
+ the rest of the line. */
+ if (strchr (buf, '\n') == NULL)
+ {
+ char altbuf[BUFSIZ];
+ do
+ if (fgets (altbuf, sizeof altbuf, fp) == NULL)
+ /* Make sure the inner loop will be left. The outer loop
+ will exit at the `feof' test. */
+ break;
+ while (strchr (altbuf, '\n') == NULL);
+ }
+
+ cp = buf;
+ /* Ignore leading white space. */
+ while (isspace (cp[0]))
+ ++cp;
+
+ /* A leading '#' signals a comment line. */
+ if (cp[0] != '\0' && cp[0] != '#')
+ {
+ alias = cp++;
+ while (cp[0] != '\0' && !isspace (cp[0]))
+ ++cp;
+ /* Terminate alias name. */
+ if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ /* Now look for the beginning of the value. */
+ while (isspace (cp[0]))
+ ++cp;
+
+ if (cp[0] != '\0')
+ {
+ size_t alias_len;
+ size_t value_len;
+
+ value = cp++;
+ while (cp[0] != '\0' && !isspace (cp[0]))
+ ++cp;
+ /* Terminate value. */
+ if (cp[0] == '\n')
+ {
+ /* This has to be done to make the following test
+ for the end of line possible. We are looking for
+ the terminating '\n' which do not overwrite here. */
+ *cp++ = '\0';
+ *cp = '\n';
+ }
+ else if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ if (nmap >= maxmap)
+ extend_alias_table ();
+
+ alias_len = strlen (alias) + 1;
+ value_len = strlen (value) + 1;
+
+ if (string_space_act + alias_len + value_len > string_space_max)
+ {
+ /* Increase size of memory pool. */
+ size_t new_size = (string_space_max
+ + (alias_len + value_len > 1024
+ ? alias_len + value_len : 1024));
+ char *new_pool = (char *) realloc (string_space, new_size);
+ if (new_pool == NULL)
+ {
+ FREE_BLOCKS (block_list);
+ return added;
+ }
+ string_space = new_pool;
+ string_space_max = new_size;
+ }
+
+ map[nmap].alias = memcpy (&string_space[string_space_act],
+ alias, alias_len);
+ string_space_act += alias_len;
+
+ map[nmap].value = memcpy (&string_space[string_space_act],
+ value, value_len);
+ string_space_act += value_len;
+
+ ++nmap;
+ ++added;
+ }
+ }
+ }
+
+ /* Should we test for ferror()? I think we have to silently ignore
+ errors. --drepper */
+ fclose (fp);
+
+ if (added > 0)
+ qsort (map, nmap, sizeof (struct alias_map),
+ (int (*) PARAMS ((const void *, const void *))) alias_compare);
+
+ FREE_BLOCKS (block_list);
+ return added;
+}
+
+
+static void
+extend_alias_table ()
+{
+ size_t new_size;
+ struct alias_map *new_map;
+
+ new_size = maxmap == 0 ? 100 : 2 * maxmap;
+ new_map = (struct alias_map *) realloc (map, (new_size
+ * sizeof (struct alias_map)));
+ if (new_map == NULL)
+ /* Simply don't extend: we don't have any more core. */
+ return;
+
+ map = new_map;
+ maxmap = new_size;
+}
+
+
+#ifdef _LIBC
+static void __attribute__ ((unused))
+free_mem (void)
+{
+ if (string_space != NULL)
+ free (string_space);
+ if (map != NULL)
+ free (map);
+}
+text_set_element (__libc_subfreeres, free_mem);
+#endif
+
+
+static int
+alias_compare (map1, map2)
+ const struct alias_map *map1;
+ const struct alias_map *map2;
+{
+#if defined _LIBC || defined HAVE_STRCASECMP
+ return strcasecmp (map1->alias, map2->alias);
+#else
+ const unsigned char *p1 = (const unsigned char *) map1->alias;
+ const unsigned char *p2 = (const unsigned char *) map2->alias;
+ unsigned char c1, c2;
+
+ if (p1 == p2)
+ return 0;
+
+ do
+ {
+ /* I know this seems to be odd but the tolower() function in
+ some systems libc cannot handle nonalpha characters. */
+ c1 = isupper (*p1) ? tolower (*p1) : *p1;
+ c2 = isupper (*p2) ? tolower (*p2) : *p2;
+ if (c1 == '\0')
+ break;
+ ++p1;
+ ++p2;
+ }
+ while (c1 == c2);
+
+ return c1 - c2;
+#endif
+}
diff --git a/current/intl/po2tbl.sed.in b/current/intl/po2tbl.sed.in
new file mode 100644
index 00000000..b3bcca4d
--- /dev/null
+++ b/current/intl/po2tbl.sed.in
@@ -0,0 +1,102 @@
+# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+1 {
+ i\
+/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\
+\
+#if HAVE_CONFIG_H\
+# include <config.h>\
+#endif\
+\
+#include "libgettext.h"\
+\
+const struct _msg_ent _msg_tbl[] = {
+ h
+ s/.*/0/
+ x
+}
+#
+# Write msgid entries in C array form.
+#
+/^msgid/ {
+ s/msgid[ ]*\(".*"\)/ {\1/
+ tb
+# Append the next line
+ :b
+ N
+# Look whether second part is continuation line.
+ s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/
+# Yes, then branch.
+ ta
+# Because we assume that the input file correctly formed the line
+# just read cannot be again be a msgid line. So it's safe to ignore
+# it.
+ s/\(.*\)\n.*/\1/
+ bc
+# We found a continuation line. But before printing insert '\'.
+ :a
+ s/\(.*\)\(\n.*\)/\1\\\2/
+ P
+# We cannot use D here.
+ s/.*\n\(.*\)/\1/
+# Some buggy seds do not clear the `successful substitution since last ``t'''
+# flag on `N', so we do a `t' here to clear it.
+ tb
+# Not reached
+ :c
+ x
+# The following nice solution is by
+# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
+ td
+# Increment a decimal number in pattern space.
+# First hide trailing `9' digits.
+ :d
+ s/9\(_*\)$/_\1/
+ td
+# Assure at least one digit is available.
+ s/^\(_*\)$/0\1/
+# Increment the last digit.
+ s/8\(_*\)$/9\1/
+ s/7\(_*\)$/8\1/
+ s/6\(_*\)$/7\1/
+ s/5\(_*\)$/6\1/
+ s/4\(_*\)$/5\1/
+ s/3\(_*\)$/4\1/
+ s/2\(_*\)$/3\1/
+ s/1\(_*\)$/2\1/
+ s/0\(_*\)$/1\1/
+# Convert the hidden `9' digits to `0's.
+ s/_/0/g
+ x
+ G
+ s/\(.*\)\n\([0-9]*\)/\1, \2},/
+ s/\(.*\)"$/\1/
+ p
+}
+#
+# Last line.
+#
+$ {
+ i\
+};\
+
+ g
+ s/0*\(.*\)/int _msg_tbl_length = \1;/p
+}
+d
diff --git a/current/intl/textdomain.c b/current/intl/textdomain.c
new file mode 100644
index 00000000..88557460
--- /dev/null
+++ b/current/intl/textdomain.c
@@ -0,0 +1,108 @@
+/* Implementation of the textdomain(3) function.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+
+/* Name of the default text domain. */
+extern const char _nl_default_default_domain[];
+
+/* Default text domain in which entries for gettext(3) are to be found. */
+extern const char *_nl_current_default_domain;
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define TEXTDOMAIN __textdomain
+# ifndef strdup
+# define strdup(str) __strdup (str)
+# endif
+#else
+# define TEXTDOMAIN textdomain__
+#endif
+
+/* Set the current default message catalog to DOMAINNAME.
+ If DOMAINNAME is null, return the current default.
+ If DOMAINNAME is "", reset to the default of "messages". */
+char *
+TEXTDOMAIN (domainname)
+ const char *domainname;
+{
+ char *old;
+
+ /* A NULL pointer requests the current setting. */
+ if (domainname == NULL)
+ return (char *) _nl_current_default_domain;
+
+ old = (char *) _nl_current_default_domain;
+
+ /* If domain name is the null string set to default domain "messages". */
+ if (domainname[0] == '\0'
+ || strcmp (domainname, _nl_default_default_domain) == 0)
+ _nl_current_default_domain = _nl_default_default_domain;
+ else
+ {
+ /* If the following malloc fails `_nl_current_default_domain'
+ will be NULL. This value will be returned and so signals we
+ are out of core. */
+#if defined _LIBC || defined HAVE_STRDUP
+ _nl_current_default_domain = strdup (domainname);
+#else
+ size_t len = strlen (domainname) + 1;
+ char *cp = (char *) malloc (len);
+ if (cp != NULL)
+ memcpy (cp, domainname, len);
+ _nl_current_default_domain = cp;
+#endif
+ }
+
+ if (old != _nl_default_default_domain)
+ free (old);
+
+ return (char *) _nl_current_default_domain;
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__textdomain, textdomain);
+#endif
diff --git a/current/intl/xopen-msg.sed b/current/intl/xopen-msg.sed
new file mode 100644
index 00000000..b19c0bbd
--- /dev/null
+++ b/current/intl/xopen-msg.sed
@@ -0,0 +1,104 @@
+# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+# The first directive in the .msg should be the definition of the
+# message set number. We use always set number 1.
+#
+1 {
+ i\
+$set 1 # Automatically created by po2msg.sed
+ h
+ s/.*/0/
+ x
+}
+#
+# We copy all comments into the .msg file. Perhaps they can help.
+#
+/^#/ s/^#[ ]*/$ /p
+#
+# We copy the original message as a comment into the .msg file.
+#
+/^msgid/ {
+# Does not work now
+# /"$/! {
+# s/\\$//
+# s/$/ ... (more lines following)"/
+# }
+ s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/
+ p
+}
+#
+# The .msg file contains, other then the .po file, only the translations
+# but each given a unique ID. Starting from 1 and incrementing by 1 for
+# each message we assign them to the messages.
+# It is important that the .po file used to generate the cat-id-tbl.c file
+# (with po-to-tbl) is the same as the one used here. (At least the order
+# of declarations must not be changed.)
+#
+/^msgstr/ {
+ s/msgstr[ ]*"\(.*\)"/\1/
+ x
+# The following nice solution is by
+# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
+ td
+# Increment a decimal number in pattern space.
+# First hide trailing `9' digits.
+ :d
+ s/9\(_*\)$/_\1/
+ td
+# Assure at least one digit is available.
+ s/^\(_*\)$/0\1/
+# Increment the last digit.
+ s/8\(_*\)$/9\1/
+ s/7\(_*\)$/8\1/
+ s/6\(_*\)$/7\1/
+ s/5\(_*\)$/6\1/
+ s/4\(_*\)$/5\1/
+ s/3\(_*\)$/4\1/
+ s/2\(_*\)$/3\1/
+ s/1\(_*\)$/2\1/
+ s/0\(_*\)$/1\1/
+# Convert the hidden `9' digits to `0's.
+ s/_/0/g
+ x
+# Bring the line in the format `<number> <message>'
+ G
+ s/^[^\n]*$/& /
+ s/\(.*\)\n\([0-9]*\)/\2 \1/
+# Clear flag from last substitution.
+ tb
+# Append the next line.
+ :b
+ N
+# Look whether second part is a continuation line.
+ s/\(.*\n\)"\(.*\)"/\1\2/
+# Yes, then branch.
+ ta
+ P
+ D
+# Note that `D' includes a jump to the start!!
+# We found a continuation line. But before printing insert '\'.
+ :a
+ s/\(.*\)\(\n.*\)/\1\\\2/
+ P
+# We cannot use the sed command `D' here
+ s/.*\n\(.*\)/\1/
+ tb
+}
+d
diff --git a/current/lib/Makefile.am b/current/lib/Makefile.am
new file mode 100644
index 00000000..f3de6fe0
--- /dev/null
+++ b/current/lib/Makefile.am
@@ -0,0 +1,57 @@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h \
+ faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h \
+ pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h \
+ tcfsio.h
+
+localedir = $(datadir)/locale
+DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
+
+# These files are unneeded for some reason, listed in
+# order of appearance:
+#
+# sources which are not really needed (are they in libc???)
+# sources for dbm support (not yet used)
+# sources for LIBOBJS (which are normally in libc)
+# misc header sources
+
+EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c \
+ grpack.c gspack.c pwpack.c sppack.c \
+ gshadow_.h shadow_.h lastlog_.h snprintf.h
+
+EXTRA_libshadow_a_SOURCESS = grent.c pwent.c \
+ mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c \
+ putgrent.c putpwent.c putspent.c \
+ sgetgrent.c sgetpwent.c sgetspent.c snprintf.c \
+ md5.c md5crypt.c
+
+# We build libshadow for our tools.
+
+noinst_LIBRARIES = libshadow.a
+
+libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c \
+ fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c \
+ pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c \
+ tcfsio.c
+
+libshadow_a_LIBADD = @LIBOBJS@
+
+INCLUDES = -I$(top_srcdir)/lib
+
+# shared library support
+libdir = ${exec_prefix}/lib
+#lib_PROGRAMS = libshadow.la
+lib_LTLIBRARIES = libshadow.la
+libshadow_la_SOURCES = ${libshadow_a_SOURCES}
+libshadow_la_LIBADD = @LTLIBOBJS@
+#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
+libshadow_la_LDFLAGS = -version-info 0:0:0
+
+# remove the libshadow.so -> libshadow.so.x.x symlink, because this
+# library is for internal use by this package only. Shadow support
+# is in libc and no one should be using -lshadow anymore.
+install-exec-hook:
+ rm -f $(libdir)/libshadow.so
+
diff --git a/current/lib/Makefile.in b/current/lib/Makefile.in
new file mode 100644
index 00000000..d28a1db4
--- /dev/null
+++ b/current/lib/Makefile.in
@@ -0,0 +1,448 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h tcfsio.h
+
+
+localedir = $(datadir)/locale
+DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
+
+# These files are unneeded for some reason, listed in
+# order of appearance:
+#
+# sources which are not really needed (are they in libc???)
+# sources for dbm support (not yet used)
+# sources for LIBOBJS (which are normally in libc)
+# misc header sources
+
+EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c grpack.c gspack.c pwpack.c sppack.c gshadow_.h shadow_.h lastlog_.h snprintf.h
+
+
+EXTRA_libshadow_a_SOURCESS = grent.c pwent.c mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c putgrent.c putpwent.c putspent.c sgetgrent.c sgetpwent.c sgetspent.c snprintf.c md5.c md5crypt.c
+
+
+# We build libshadow for our tools.
+
+noinst_LIBRARIES = libshadow.a
+
+libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c tcfsio.c
+
+
+libshadow_a_LIBADD = @LIBOBJS@
+
+INCLUDES = -I$(top_srcdir)/lib
+
+# shared library support
+libdir = ${exec_prefix}/lib
+#lib_PROGRAMS = libshadow.la
+lib_LTLIBRARIES = libshadow.la
+libshadow_la_SOURCES = ${libshadow_a_SOURCES}
+libshadow_la_LIBADD = @LTLIBOBJS@
+#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
+libshadow_la_LDFLAGS = -version-info 0:0:0
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libshadow_a_DEPENDENCIES = @LIBOBJS@
+libshadow_a_OBJECTS = commonio.o dialchk.o dialup.o encrypt.o fputsx.o \
+getdef.o getpass.o groupio.o gshadow.o lockpw.o port.o pwauth.o pwio.o \
+rad64.o sgroupio.o shadow.o shadowio.o utent.o tcfsio.o
+AR = ar
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libshadow_la_DEPENDENCIES = @LTLIBOBJS@
+libshadow_la_OBJECTS = commonio.lo dialchk.lo dialup.lo encrypt.lo \
+fputsx.lo getdef.lo getpass.lo groupio.lo gshadow.lo lockpw.lo port.lo \
+pwauth.lo pwio.lo rad64.lo sgroupio.lo shadow.lo shadowio.lo utent.lo \
+tcfsio.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in md5.c md5crypt.c mkdir.c \
+putgrent.c putpwent.c putspent.c rename.c rmdir.c sgetgrent.c \
+sgetpwent.c sgetspent.c snprintf.c strcasecmp.c strdup.c strerror.c \
+strstr.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libshadow_a_SOURCES) $(libshadow_la_SOURCES)
+OBJECTS = $(libshadow_a_OBJECTS) $(libshadow_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps lib/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libshadow.a: $(libshadow_a_OBJECTS) $(libshadow_a_DEPENDENCIES)
+ -rm -f libshadow.a
+ $(AR) cru libshadow.a $(libshadow_a_OBJECTS) $(libshadow_a_LIBADD)
+ $(RANLIB) libshadow.a
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+libshadow.la: $(libshadow_la_OBJECTS) $(libshadow_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libshadow_la_LDFLAGS) $(libshadow_la_OBJECTS) $(libshadow_la_LIBADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+commonio.lo commonio.o : commonio.c ../config.h rcsid.h defines.h \
+ gshadow_.h commonio.h
+dialchk.lo dialchk.o : dialchk.c ../config.h rcsid.h defines.h \
+ gshadow_.h prototypes.h dialup.h dialchk.h
+dialup.lo dialup.o : dialup.c ../config.h rcsid.h prototypes.h defines.h \
+ gshadow_.h dialup.h
+encrypt.lo encrypt.o : encrypt.c ../config.h rcsid.h prototypes.h \
+ defines.h gshadow_.h
+fputsx.lo fputsx.o : fputsx.c ../config.h defines.h gshadow_.h rcsid.h
+getdef.lo getdef.o : getdef.c ../config.h rcsid.h prototypes.h defines.h \
+ gshadow_.h getdef.h
+getpass.lo getpass.o : getpass.c ../config.h rcsid.h defines.h \
+ gshadow_.h getdef.h
+groupio.lo groupio.o : groupio.c ../config.h rcsid.h prototypes.h \
+ defines.h gshadow_.h commonio.h groupio.h
+gshadow.lo gshadow.o : gshadow.c ../config.h rcsid.h prototypes.h \
+ defines.h gshadow_.h
+lockpw.lo lockpw.o : lockpw.c ../config.h
+port.lo port.o : port.c ../config.h rcsid.h defines.h gshadow_.h port.h
+putgrent.lo putgrent.o : putgrent.c ../config.h prototypes.h defines.h \
+ gshadow_.h
+pwauth.lo pwauth.o : pwauth.c ../config.h rcsid.h prototypes.h defines.h \
+ gshadow_.h pwauth.h getdef.h
+pwio.lo pwio.o : pwio.c ../config.h rcsid.h prototypes.h defines.h \
+ gshadow_.h commonio.h pwio.h
+rad64.lo rad64.o : rad64.c ../config.h rcsid.h
+sgetgrent.lo sgetgrent.o : sgetgrent.c ../config.h rcsid.h defines.h \
+ gshadow_.h
+sgetpwent.lo sgetpwent.o : sgetpwent.c ../config.h rcsid.h defines.h \
+ gshadow_.h
+sgroupio.lo sgroupio.o : sgroupio.c ../config.h rcsid.h prototypes.h \
+ defines.h gshadow_.h commonio.h sgroupio.h
+shadowio.lo shadowio.o : shadowio.c ../config.h rcsid.h prototypes.h \
+ defines.h gshadow_.h commonio.h shadowio.h
+shadow.lo shadow.o : shadow.c ../config.h
+tcfsio.lo tcfsio.o : tcfsio.c ../config.h
+utent.lo utent.o : utent.c ../config.h
+
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-libLTLIBRARIES \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLIBRARIES clean-compile clean-libtool \
+ clean-libLTLIBRARIES clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLIBRARIES distclean-compile \
+ distclean-libtool distclean-libLTLIBRARIES \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-libLTLIBRARIES maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool mostlyclean-libLTLIBRARIES \
+distclean-libLTLIBRARIES clean-libLTLIBRARIES \
+maintainer-clean-libLTLIBRARIES uninstall-libLTLIBRARIES \
+install-libLTLIBRARIES tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# remove the libshadow.so -> libshadow.so.x.x symlink, because this
+# library is for internal use by this package only. Shadow support
+# is in libc and no one should be using -lshadow anymore.
+install-exec-hook:
+ rm -f $(libdir)/libshadow.so
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/lib/commonio.c b/current/lib/commonio.c
new file mode 100644
index 00000000..4adb8eee
--- /dev/null
+++ b/current/lib/commonio.c
@@ -0,0 +1,803 @@
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: commonio.c,v 1.16 2000/09/02 18:40:42 marekm Exp $")
+
+#include "defines.h"
+#include <sys/stat.h>
+#include <utime.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <pwd.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+#include "commonio.h"
+
+/* local function prototypes */
+static int check_link_count(const char *);
+static int do_lock_file(const char *, const char *);
+static FILE *fopen_set_perms(const char *, const char *, const struct stat *);
+static int create_backup(const char *, FILE *);
+static void free_linked_list(struct commonio_db *);
+static void add_one_entry(struct commonio_db *, struct commonio_entry *);
+static int name_is_nis(const char *);
+static int write_all(const struct commonio_db *);
+static struct commonio_entry *find_entry_by_name(struct commonio_db *, const char *);
+
+static int lock_count = 0;
+static int nscd_need_reload = 0;
+
+static int
+check_link_count(const char *file)
+{
+ struct stat sb;
+
+ if (stat(file, &sb) != 0)
+ return 0;
+
+ if (sb.st_nlink != 2)
+ return 0;
+
+ return 1;
+}
+
+
+static int
+do_lock_file(const char *file, const char *lock)
+{
+ int fd;
+ int pid;
+ int len;
+ int retval;
+ char buf[32];
+
+ if ((fd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0600)) == -1)
+ return 0;
+
+ pid = getpid();
+ snprintf(buf, sizeof buf, "%d", pid);
+ len = strlen(buf) + 1;
+ if (write(fd, buf, len) != len) {
+ close(fd);
+ unlink(file);
+ return 0;
+ }
+ close(fd);
+
+ if (link(file, lock) == 0) {
+ retval = check_link_count(file);
+ unlink(file);
+ return retval;
+ }
+
+ if ((fd = open(lock, O_RDWR)) == -1) {
+ unlink(file);
+ errno = EINVAL;
+ return 0;
+ }
+ len = read(fd, buf, sizeof(buf) - 1);
+ close(fd);
+ if (len <= 0) {
+ unlink(file);
+ errno = EINVAL;
+ return 0;
+ }
+ buf[len] = '\0';
+ if ((pid = strtol(buf, (char **) 0, 10)) == 0) {
+ unlink(file);
+ errno = EINVAL;
+ return 0;
+ }
+ if (kill(pid, 0) == 0) {
+ unlink(file);
+ errno = EEXIST;
+ return 0;
+ }
+ if (unlink(lock) != 0) {
+ unlink(file);
+ return 0;
+ }
+
+ retval = 0;
+ if (link(file, lock) == 0 && check_link_count(file))
+ retval = 1;
+
+ unlink(file);
+ return retval;
+}
+
+
+static FILE *
+fopen_set_perms(const char *name, const char *mode, const struct stat *sb)
+{
+ FILE *fp;
+ mode_t mask;
+
+ mask = umask(0777);
+ fp = fopen(name, mode);
+ umask(mask);
+ if (!fp)
+ return NULL;
+
+#ifdef HAVE_FCHOWN
+ if (fchown(fileno(fp), sb->st_uid, sb->st_gid))
+ goto fail;
+#else
+ if (chown(name, sb->st_mode))
+ goto fail;
+#endif
+
+#ifdef HAVE_FCHMOD
+ if (fchmod(fileno(fp), sb->st_mode & 0664))
+ goto fail;
+#else
+ if (chmod(name, sb->st_mode & 0664))
+ goto fail;
+#endif
+ return fp;
+
+fail:
+ fclose(fp);
+ unlink(name);
+ return NULL;
+}
+
+
+static int
+create_backup(const char *backup, FILE *fp)
+{
+ struct stat sb;
+ struct utimbuf ub;
+ FILE *bkfp;
+ int c;
+ mode_t mask;
+
+ if (fstat(fileno(fp), &sb))
+ return -1;
+
+ mask = umask(077);
+ bkfp = fopen(backup, "w");
+ umask(mask);
+ if (!bkfp)
+ return -1;
+
+ /* TODO: faster copy, not one-char-at-a-time. --marekm */
+ rewind(fp);
+ while ((c = getc(fp)) != EOF) {
+ if (putc(c, bkfp) == EOF)
+ break;
+ }
+ if (c != EOF || fflush(bkfp)) {
+ fclose(bkfp);
+ return -1;
+ }
+ if (fclose(bkfp))
+ return -1;
+
+ ub.actime = sb.st_atime;
+ ub.modtime = sb.st_mtime;
+ utime(backup, &ub);
+ return 0;
+}
+
+
+static void
+free_linked_list(struct commonio_db *db)
+{
+ struct commonio_entry *p;
+
+ while (db->head) {
+ p = db->head;
+ db->head = p->next;
+
+ if (p->line)
+ free(p->line);
+
+ if (p->eptr)
+ db->ops->free(p->eptr);
+
+ free(p);
+ }
+ db->tail = NULL;
+}
+
+
+int
+commonio_setname(struct commonio_db *db, const char *name)
+{
+ strcpy(db->filename, name);
+ return 1;
+}
+
+
+int
+commonio_present(const struct commonio_db *db)
+{
+ return (access(db->filename, F_OK) == 0);
+}
+
+
+int
+commonio_lock_nowait(struct commonio_db *db)
+{
+ char file[1024];
+ char lock[1024];
+
+ if (db->locked)
+ return 1;
+
+ snprintf(file, sizeof file, "%s.%ld", db->filename, (long) getpid());
+ snprintf(lock, sizeof lock, "%s.lock", db->filename);
+ if (do_lock_file(file, lock)) {
+ db->locked = 1;
+ lock_count++;
+ return 1;
+ }
+ return 0;
+}
+
+
+int
+commonio_lock(struct commonio_db *db)
+{
+#ifdef HAVE_LCKPWDF
+ /*
+ * only if the system libc has a real lckpwdf() - the one from
+ * lockpw.c calls us and would cause infinite recursion!
+ */
+
+ /*
+ * Call lckpwdf() on the first lock.
+ * If it succeeds, call *_lock() only once
+ * (no retries, it should always succeed).
+ */
+ if (lock_count == 0) {
+ if (lckpwdf() == -1)
+ return 0; /* failure */
+ }
+
+ if (commonio_lock_nowait(db))
+ return 1; /* success */
+
+ ulckpwdf();
+ return 0; /* failure */
+#else
+ int i;
+
+ /*
+ * lckpwdf() not used - do it the old way.
+ */
+#ifndef LOCK_TRIES
+#define LOCK_TRIES 15
+#endif
+
+#ifndef LOCK_SLEEP
+#define LOCK_SLEEP 1
+#endif
+ for (i = 0; i < LOCK_TRIES; i++) {
+ if (i > 0)
+ sleep(LOCK_SLEEP); /* delay between retries */
+ if (commonio_lock_nowait(db))
+ return 1; /* success */
+ /* no unnecessary retries on "permission denied" errors */
+ if (geteuid() != 0)
+ return 0;
+ }
+ return 0; /* failure */
+#endif
+}
+
+#ifndef NSCD_PID_FILE
+#define NSCD_PID_FILE "/var/run/nscd.pid"
+#endif
+
+/*
+ reload_nscd() is called after updating all of the password files,
+ to tell the "nscd" caching daemon to clear its cache.
+ Very loosely based on a shadow-utils patch from Red Hat.
+ */
+
+static void
+reload_nscd(void)
+{
+ FILE *pidfile;
+ int pid;
+
+ pidfile = fopen(NSCD_PID_FILE, "r");
+ if (pidfile) {
+ pid = 0;
+ fscanf(pidfile, "%d", &pid);
+ if (pid > 0)
+ kill(pid, SIGHUP);
+ fclose(pidfile);
+ }
+}
+
+
+static void
+dec_lock_count(void)
+{
+ if (lock_count > 0) {
+ lock_count--;
+ if (lock_count == 0) {
+ /* Tell nscd when lock count goes to zero,
+ if any of the files were changed. */
+ if (nscd_need_reload) {
+ reload_nscd();
+ nscd_need_reload = 0;
+ }
+#ifdef HAVE_LCKPWDF
+ ulckpwdf();
+#endif
+ }
+ }
+}
+
+
+int
+commonio_unlock(struct commonio_db *db)
+{
+ char lock[1024];
+
+ if (db->isopen) {
+ db->readonly = 1;
+ if (!commonio_close(db)) {
+ if (db->locked)
+ dec_lock_count();
+ return 0;
+ }
+ }
+ if (db->locked) {
+ /*
+ * Unlock in reverse order: remove the lock file,
+ * then call ulckpwdf() (if used) on last unlock.
+ */
+ db->locked = 0;
+ snprintf(lock, sizeof lock, "%s.lock", db->filename);
+ unlink(lock);
+ dec_lock_count();
+ return 1;
+ }
+ return 0;
+}
+
+
+static void
+add_one_entry(struct commonio_db *db, struct commonio_entry *p)
+{
+ p->next = NULL;
+ p->prev = db->tail;
+ if (!db->head)
+ db->head = p;
+ if (db->tail)
+ db->tail->next = p;
+ db->tail = p;
+}
+
+
+static int
+name_is_nis(const char *n)
+{
+ return (n[0] == '+' || n[0] == '-');
+}
+
+
+/*
+ * New entries are inserted before the first NIS entry. Order is preserved
+ * when db is written out.
+ */
+#ifndef KEEP_NIS_AT_END
+#define KEEP_NIS_AT_END 1
+#endif
+
+#if KEEP_NIS_AT_END
+static void add_one_entry_nis(struct commonio_db *, struct commonio_entry *);
+
+static void
+add_one_entry_nis(struct commonio_db *db, struct commonio_entry *newp)
+{
+ struct commonio_entry *p;
+
+ for (p = db->head; p; p = p->next) {
+ if (name_is_nis(p->eptr ? db->ops->getname(p->eptr) : p->line)) {
+ newp->next = p;
+ newp->prev = p->prev;
+ if (p->prev)
+ p->prev->next = newp;
+ else
+ db->head = newp;
+ p->prev = newp;
+ return;
+ }
+ }
+ add_one_entry(db, newp);
+}
+#endif /* KEEP_NIS_AT_END */
+
+/* Initial buffer size, as well as increment if not sufficient
+ (for reading very long lines in group files). */
+#define BUFLEN 4096
+
+int
+commonio_open(struct commonio_db *db, int mode)
+{
+ char *buf;
+ char *cp;
+ char *line;
+ struct commonio_entry *p;
+ void *eptr;
+ int flags = mode;
+ int buflen;
+
+ mode &= ~O_CREAT;
+
+ if (db->isopen || (mode != O_RDONLY && mode != O_RDWR)) {
+ errno = EINVAL;
+ return 0;
+ }
+ db->readonly = (mode == O_RDONLY);
+ if (!db->readonly && !db->locked) {
+ errno = EACCES;
+ return 0;
+ }
+
+ db->head = db->tail = db->cursor = NULL;
+ db->changed = 0;
+
+ db->fp = fopen(db->filename, db->readonly ? "r" : "r+");
+
+ /*
+ * If O_CREAT was specified and the file didn't exist, it will be
+ * created by commonio_close(). We have no entries to read yet. --marekm
+ */
+ if (!db->fp) {
+ if ((flags & O_CREAT) && errno == ENOENT) {
+ db->isopen = 1;
+ return 1;
+ }
+ return 0;
+ }
+
+ buflen = BUFLEN;
+ buf = (char *) malloc(buflen);
+ if (!buf)
+ goto cleanup;
+
+ while (db->ops->fgets(buf, buflen, db->fp)) {
+ while (!(cp = strrchr(buf, '\n')) && !feof(db->fp)) {
+ buflen += BUFLEN;
+ cp = (char *) realloc(buf, buflen);
+ if (!cp)
+ goto cleanup_buf;
+ buf = cp;
+ db->ops->fgets(buf + buflen - BUFLEN, BUFLEN, db->fp);
+ }
+ if ((cp = strrchr(buf, '\n')))
+ *cp = '\0';
+
+ if (!(line = strdup(buf)))
+ goto cleanup_buf;
+
+ if (name_is_nis(line)) {
+ eptr = NULL;
+ } else if ((eptr = db->ops->parse(line))) {
+ eptr = db->ops->dup(eptr);
+ if (!eptr)
+ goto cleanup_line;
+ }
+
+ p = (struct commonio_entry *) malloc(sizeof *p);
+ if (!p)
+ goto cleanup_entry;
+
+ p->eptr = eptr;
+ p->line = line;
+ p->changed = 0;
+
+ add_one_entry(db, p);
+ }
+
+ db->isopen = 1;
+ free(buf);
+ return 1;
+
+cleanup_entry:
+ if (eptr)
+ db->ops->free(eptr);
+cleanup_line:
+ free(line);
+cleanup_buf:
+ free(buf);
+cleanup:
+ free_linked_list(db);
+ fclose(db->fp);
+ db->fp = NULL;
+ errno = ENOMEM;
+ return 0;
+}
+
+
+static int
+write_all(const struct commonio_db *db)
+{
+ const struct commonio_entry *p;
+ void *eptr;
+
+ for (p = db->head; p; p = p->next) {
+ if (p->changed) {
+ eptr = p->eptr;
+ if (db->ops->put(eptr, db->fp))
+ return -1;
+ } else if (p->line) {
+ if (db->ops->fputs(p->line, db->fp) == EOF)
+ return -1;
+ if (putc('\n', db->fp) == EOF)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+int
+commonio_close(struct commonio_db *db)
+{
+ char buf[1024];
+ int errors = 0;
+ struct stat sb;
+
+ if (!db->isopen) {
+ errno = EINVAL;
+ return 0;
+ }
+ db->isopen = 0;
+
+ if (!db->changed || db->readonly) {
+ fclose(db->fp);
+ db->fp = NULL;
+ goto success;
+ }
+
+ memzero(&sb, sizeof sb);
+ if (db->fp) {
+ if (fstat(fileno(db->fp), &sb)) {
+ fclose(db->fp);
+ db->fp = NULL;
+ goto fail;
+ }
+
+ /*
+ * Create backup file.
+ */
+ snprintf(buf, sizeof buf, "%s-", db->filename);
+
+ if (create_backup(buf, db->fp))
+ errors++;
+
+ if (fclose(db->fp))
+ errors++;
+
+ if (errors) {
+ db->fp = NULL;
+ goto fail;
+ }
+ } else {
+ /*
+ * Default permissions for new [g]shadow files.
+ * (passwd and group always exist...)
+ */
+ sb.st_mode = 0400;
+ sb.st_uid = 0;
+ sb.st_gid = 0;
+ }
+
+ snprintf(buf, sizeof buf, "%s+", db->filename);
+
+ db->fp = fopen_set_perms(buf, "w", &sb);
+ if (!db->fp)
+ goto fail;
+
+ if (write_all(db))
+ errors++;
+
+ if (fflush(db->fp))
+ errors++;
+#ifdef HAVE_FSYNC
+ if (fsync(fileno(db->fp)))
+ errors++;
+#else
+ sync();
+#endif
+ if (fclose(db->fp))
+ errors++;
+
+ db->fp = NULL;
+
+ if (errors) {
+ unlink(buf);
+ goto fail;
+ }
+
+ if (rename(buf, db->filename))
+ goto fail;
+
+ nscd_need_reload = 1;
+
+success:
+ free_linked_list(db);
+ return 1;
+
+fail:
+ free_linked_list(db);
+ return 0;
+}
+
+
+static struct commonio_entry *
+find_entry_by_name(struct commonio_db *db, const char *name)
+{
+ struct commonio_entry *p;
+ void *ep;
+
+ for (p = db->head; p; p = p->next) {
+ ep = p->eptr;
+ if (ep && strcmp(db->ops->getname(ep), name) == 0)
+ break;
+ }
+ return p;
+}
+
+
+int
+commonio_update(struct commonio_db *db, const void *eptr)
+{
+ struct commonio_entry *p;
+ void *nentry;
+
+ if (!db->isopen || db->readonly) {
+ errno = EINVAL;
+ return 0;
+ }
+ if (!(nentry = db->ops->dup(eptr))) {
+ errno = ENOMEM;
+ return 0;
+ }
+ p = find_entry_by_name(db, db->ops->getname(eptr));
+ if (p) {
+ db->ops->free(p->eptr);
+ p->eptr = nentry;
+ p->changed = 1;
+ db->cursor = p;
+
+ db->changed = 1;
+ return 1;
+ }
+ /* not found, new entry */
+ p = (struct commonio_entry *) malloc(sizeof *p);
+ if (!p) {
+ db->ops->free(nentry);
+ errno = ENOMEM;
+ return 0;
+ }
+
+ p->eptr = nentry;
+ p->line = NULL;
+ p->changed = 1;
+
+#if KEEP_NIS_AT_END
+ add_one_entry_nis(db, p);
+#else
+ add_one_entry(db, p);
+#endif
+
+ db->changed = 1;
+ return 1;
+}
+
+
+void
+commonio_del_entry(struct commonio_db *db, const struct commonio_entry *p)
+{
+ if (p == db->cursor)
+ db->cursor = p->next;
+
+ if (p->prev)
+ p->prev->next = p->next;
+ else
+ db->head = p->next;
+
+ if (p->next)
+ p->next->prev = p->prev;
+ else
+ db->tail = p->prev;
+
+ db->changed = 1;
+}
+
+
+int
+commonio_remove(struct commonio_db *db, const char *name)
+{
+ struct commonio_entry *p;
+
+ if (!db->isopen || db->readonly) {
+ errno = EINVAL;
+ return 0;
+ }
+ p = find_entry_by_name(db, name);
+ if (!p) {
+ errno = ENOENT;
+ return 0;
+ }
+
+ commonio_del_entry(db, p);
+
+ if (p->line)
+ free(p->line);
+
+ if (p->eptr)
+ db->ops->free(p->eptr);
+
+ return 1;
+}
+
+
+const void *
+commonio_locate(struct commonio_db *db, const char *name)
+{
+ struct commonio_entry *p;
+
+ if (!db->isopen) {
+ errno = EINVAL;
+ return NULL;
+ }
+ p = find_entry_by_name(db, name);
+ if (!p) {
+ errno = ENOENT;
+ return NULL;
+ }
+ db->cursor = p;
+ return p->eptr;
+}
+
+
+int
+commonio_rewind(struct commonio_db *db)
+{
+ if (!db->isopen) {
+ errno = EINVAL;
+ return 0;
+ }
+ db->cursor = NULL;
+ return 1;
+}
+
+
+const void *
+commonio_next(struct commonio_db *db)
+{
+ void *eptr;
+
+ if (!db->isopen) {
+ errno = EINVAL;
+ return 0;
+ }
+ if (db->cursor == NULL)
+ db->cursor = db->head;
+ else
+ db->cursor = db->cursor->next;
+
+ while (db->cursor) {
+ eptr = db->cursor->eptr;
+ if (eptr)
+ return eptr;
+
+ db->cursor = db->cursor->next;
+ }
+ return NULL;
+}
diff --git a/current/lib/commonio.h b/current/lib/commonio.h
new file mode 100644
index 00000000..f25883b8
--- /dev/null
+++ b/current/lib/commonio.h
@@ -0,0 +1,100 @@
+/* $Id: commonio.h,v 1.6 2000/09/02 18:40:43 marekm Exp $ */
+
+/*
+ * Linked list entry.
+ */
+struct commonio_entry {
+ char *line;
+ void *eptr; /* struct passwd, struct spwd, ... */
+ struct commonio_entry *prev, *next;
+ int changed:1;
+};
+
+/*
+ * Operations depending on database type: passwd, group, shadow etc.
+ */
+struct commonio_ops {
+ /*
+ * Make a copy of the object (for example, struct passwd)
+ * and all strings pointed by it, in malloced memory.
+ */
+ void *(*dup)(const void *);
+
+ /*
+ * free() the object including any strings pointed by it.
+ */
+ void (*free)(void *);
+
+ /*
+ * Return the name of the object (for example, pw_name
+ * for struct passwd).
+ */
+ const char *(*getname)(const void *);
+
+ /*
+ * Parse a string, return object (in static area -
+ * should be copied using the dup operation above).
+ */
+ void *(*parse)(const char *);
+
+ /*
+ * Write the object to the file (this calls putpwent()
+ * for struct passwd, for example).
+ */
+ int (*put)(const void *, FILE *);
+
+ /*
+ * fgets and fputs (can be replaced by versions that
+ * understand line continuation conventions).
+ */
+ char *(*fgets)(char *, int, FILE *);
+ int (*fputs)(const char *, FILE *);
+};
+
+/*
+ * Database structure.
+ */
+struct commonio_db {
+ /*
+ * Name of the data file.
+ */
+ char filename[1024];
+
+ /*
+ * Operations from above.
+ */
+ struct commonio_ops *ops;
+
+ /*
+ * Currently open file stream.
+ */
+ FILE *fp;
+
+ /*
+ * Head, tail, current position in linked list.
+ */
+ struct commonio_entry *head, *tail, *cursor;
+
+ /*
+ * Various flags.
+ */
+ int changed:1;
+ int isopen:1;
+ int locked:1;
+ int readonly:1;
+};
+
+extern int commonio_setname(struct commonio_db *, const char *);
+extern int commonio_present(const struct commonio_db *);
+extern int commonio_lock(struct commonio_db *);
+extern int commonio_lock_nowait(struct commonio_db *);
+extern int commonio_open(struct commonio_db *, int);
+extern const void *commonio_locate(struct commonio_db *, const char *);
+extern int commonio_update(struct commonio_db *, const void *);
+extern int commonio_remove(struct commonio_db *, const char *);
+extern int commonio_rewind(struct commonio_db *);
+extern const void *commonio_next(struct commonio_db *);
+extern int commonio_close(struct commonio_db *);
+extern int commonio_unlock(struct commonio_db *);
+extern void commonio_del_entry(struct commonio_db *, const struct commonio_entry *);
+
diff --git a/current/lib/defines.h b/current/lib/defines.h
new file mode 100644
index 00000000..c020f9e5
--- /dev/null
+++ b/current/lib/defines.h
@@ -0,0 +1,348 @@
+/* $Id: defines.h,v 1.17 2000/09/02 18:40:43 marekm Exp $ */
+/* some useful defines */
+
+#ifndef _DEFINES_H_
+#define _DEFINES_H_
+
+#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+
+/* Take care of NLS matters. */
+
+#if HAVE_LOCALE_H
+# include <locale.h>
+#endif
+#if !HAVE_SETLOCALE
+# define setlocale(Category, Locale) /* empty */
+#endif
+
+#define gettext_noop(String) (String)
+/* #define gettext_def(String) "#define String" */
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# undef bindtextdomain
+# define bindtextdomain(Domain, Directory) /* empty */
+# undef textdomain
+# define textdomain(Domain) /* empty */
+# define _(Text) Text
+#endif
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else /* not STDC_HEADERS */
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr(), *strtok();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy((s), (d), (n))
+# endif
+#endif /* not STDC_HEADERS */
+
+/* Solaris 2.4 defines __SVR4, but not SVR4 -j. */
+
+#ifdef __SVR4
+# ifndef SVR4
+# define SVR4 __SVR4
+# endif
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else /* not TIME_WITH_SYS_TIME */
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif /* not TIME_WITH_SYS_TIME */
+
+#ifdef HAVE_MEMSET
+# define memzero(ptr, size) memset((void *)(ptr), 0, (size))
+#else
+# define memzero(ptr, size) bzero((char *)(ptr), (size))
+#endif
+#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
+
+#ifdef HAVE_DIRENT_H /* DIR_SYSV */
+# include <dirent.h>
+# define DIRECT dirent
+#else
+# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */
+# include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H /* DIR_??? */
+# include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H /* DIR_BSD */
+# include <ndir.h>
+# endif
+# define DIRECT direct
+#endif
+
+#ifdef SHADOWPWD
+/*
+ * Possible cases:
+ * - /usr/include/shadow.h exists and includes the shadow group stuff.
+ * - /usr/include/shadow.h exists, but we use our own gshadow.h.
+ * - /usr/include/shadow.h doesn't exist, use our own shadow.h and gshadow.h.
+ */
+#if HAVE_SHADOW_H
+#include <shadow.h>
+#if defined(SHADOWGRP) && !defined(GSHADOW)
+#include "gshadow_.h"
+#endif
+#else /* not HAVE_SHADOW_H */
+#include "shadow_.h"
+#ifdef SHADOWGRP
+#include "gshadow_.h"
+#endif
+#endif /* not HAVE_SHADOW_H */
+#endif /* SHADOWPWD */
+
+#include <limits.h>
+
+#ifndef NGROUPS_MAX
+#ifdef NGROUPS
+#define NGROUPS_MAX NGROUPS
+#else
+#define NGROUPS_MAX 64
+#endif
+#endif
+
+#ifdef USE_SYSLOG
+#include <syslog.h>
+
+#ifndef LOG_WARN
+#define LOG_WARN LOG_WARNING
+#endif
+
+/* LOG_NOWAIT is deprecated */
+#ifndef LOG_NOWAIT
+#define LOG_NOWAIT 0
+#endif
+
+/* LOG_AUTH is deprecated, use LOG_AUTHPRIV instead */
+#ifndef LOG_AUTHPRIV
+#define LOG_AUTHPRIV LOG_AUTH
+#endif
+
+/* cleaner than lots of #ifdefs everywhere - use this as follows:
+ SYSLOG((LOG_CRIT, "user %s cracked root", user)); */
+#if HAVE_SETLOCALE
+/* Temporarily set LC_TIME to "C" to avoid strange dates in syslog.
+ This is a workaround for a more general syslog(d) design problem -
+ syslogd should log the current system time for each event, and not
+ trust the formatted time received from the unix domain (or worse,
+ UDP) socket. -MM */
+#define SYSLOG(x) \
+ do { \
+ char *saved_locale = setlocale(LC_ALL, NULL); \
+ if (saved_locale) \
+ saved_locale = strdup(saved_locale); \
+ if (saved_locale) \
+ setlocale(LC_TIME, "C"); \
+ syslog x ; \
+ if (saved_locale) { \
+ setlocale(LC_ALL, saved_locale); \
+ free(saved_locale); \
+ } \
+ } while (0)
+#else /* !HAVE_SETLOCALE */
+#define SYSLOG(x) syslog x
+#endif /* !HAVE_SETLOCALE */
+
+#else /* !USE_SYSLOG */
+
+#define SYSLOG(x) /* empty */
+#define openlog(a,b,c) /* empty */
+#define closelog() /* empty */
+
+#endif /* !USE_SYSLOG */
+
+/* The default syslog settings can now be changed here,
+ in just one place. */
+
+#ifndef SYSLOG_OPTIONS
+/* #define SYSLOG_OPTIONS (LOG_PID | LOG_CONS | LOG_NOWAIT) */
+#define SYSLOG_OPTIONS (LOG_PID)
+#endif
+
+#ifndef SYSLOG_FACILITY
+#define SYSLOG_FACILITY LOG_AUTHPRIV
+#endif
+
+#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
+
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+
+#ifdef STAT_MACROS_BROKEN
+# define S_ISDIR(x) ((x) & S_IFMT) == S_IFDIR)
+# define S_ISREG(x) ((x) & S_IFMT) == S_IFREG)
+# ifdef S_IFLNK
+# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK)
+# endif
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(x) (0)
+#endif
+
+#if HAVE_LCHOWN
+#define LCHOWN lchown
+#else
+#define LCHOWN chown
+#endif
+
+#if HAVE_LSTAT
+#define LSTAT lstat
+#else
+#define LSTAT stat
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
+# define GTTY(fd, termio) tcgetattr(fd, termio)
+# define TERMIO struct termios
+# define USE_TERMIOS
+#else /* assumed HAVE_TERMIO_H */
+# include <sys/ioctl.h>
+# include <termio.h>
+# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
+# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
+# define TEMRIO struct termio
+# define USE_TERMIO
+#endif
+
+/*
+ * Password aging constants
+ *
+ * DAY - seconds / day
+ * WEEK - seconds / week
+ * SCALE - seconds / aging unit
+ */
+
+/* Solaris defines this in shadow.h */
+#ifndef DAY
+#define DAY (24L*3600L)
+#endif
+
+#define WEEK (7*DAY)
+
+#ifdef ITI_AGING
+#define SCALE 1
+#else
+#define SCALE DAY
+#endif
+
+/* Copy string pointed by B to array A with size checking. It was originally
+ in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
+ very sloppy coding used to assume that BUFSIZ will always be enough... */
+
+ /* danger - side effects */
+#define STRFCPY(A,B) \
+ (strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
+
+/* get rid of a few ugly repeated #ifdefs in pwent.c and grent.c */
+/* XXX - this is ugly too, configure should test it and not check for
+ any hardcoded system names, if possible. --marekm */
+#if defined(SVR4) || defined(AIX) || defined(__linux__)
+#define SETXXENT_TYPE void
+#define SETXXENT_RET(x) return
+#define SETXXENT_TEST(x) x; if (0) /* compiler should optimize this away */
+#else
+#define SETXXENT_TYPE int
+#define SETXXENT_RET(x) return(x)
+#define SETXXENT_TEST(x) if (x)
+#endif
+
+#ifndef PASSWD_FILE
+#define PASSWD_FILE "/etc/passwd"
+#endif
+
+#ifndef GROUP_FILE
+#define GROUP_FILE "/etc/group"
+#endif
+
+#ifdef SHADOWPWD
+#ifndef SHADOW_FILE
+#define SHADOW_FILE "/etc/shadow"
+#endif
+#endif
+
+#ifdef SHADOWGRP
+#ifndef SGROUP_FILE
+#define SGROUP_FILE "/etc/gshadow"
+#endif
+#endif
+
+#define PASSWD_PAG_FILE PASSWD_FILE ".pag"
+#define GROUP_PAG_FILE GROUP_FILE ".pag"
+#define SHADOW_PAG_FILE SHADOW_FILE ".pag"
+#define SGROUP_PAG_FILE SGROUP_FILE ".pag"
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#ifdef sun /* hacks for compiling on SunOS */
+# ifndef SOLARIS
+extern int fputs();
+extern char *strdup();
+extern char *strerror();
+# endif
+#endif
+
+#ifndef HAVE_SNPRINTF
+#include "snprintf.h"
+#endif
+
+/*
+ * string to use for the pw_passwd field in /etc/passwd when using
+ * shadow passwords - most systems use "x" but there are a few
+ * exceptions, so it can be changed here if necessary. --marekm
+ */
+#ifndef SHADOW_PASSWD_STRING
+#define SHADOW_PASSWD_STRING "x"
+#endif
+
+#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
+#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
+#else
+#define PAM_STRERROR(pamh, err) pam_strerror(err)
+#endif
+
+#endif /* _DEFINES_H_ */
diff --git a/current/lib/dialchk.c b/current/lib/dialchk.c
new file mode 100644
index 00000000..92b4ce7e
--- /dev/null
+++ b/current/lib/dialchk.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: dialchk.c,v 1.6 1999/08/27 19:02:51 marekm Exp $")
+
+#include <stdio.h>
+#include "defines.h"
+#include "prototypes.h"
+#include "dialup.h"
+#include "dialchk.h"
+
+/*
+ * Check for dialup password
+ *
+ * dialcheck tests to see if tty is listed as being a dialup
+ * line. If so, a dialup password may be required if the shell
+ * is listed as one which requires a second password.
+ */
+
+int
+dialcheck(const char *tty, const char *sh)
+{
+ struct dialup *dialup;
+ char *pass;
+ char *cp;
+
+ setduent ();
+
+ if (! isadialup (tty)) {
+ endduent ();
+ return (1);
+ }
+ if (! (dialup = getdushell (sh))) {
+ endduent ();
+ return (1);
+ }
+ endduent ();
+
+ if (dialup->du_passwd[0] == '\0')
+ return (1);
+
+ if (! (pass = getpass(_("Dialup Password: "))))
+ return (0);
+
+ cp = pw_encrypt (pass, dialup->du_passwd);
+ strzero(pass);
+ return (strcmp (cp, dialup->du_passwd) == 0);
+}
diff --git a/current/lib/dialchk.h b/current/lib/dialchk.h
new file mode 100644
index 00000000..75f1829e
--- /dev/null
+++ b/current/lib/dialchk.h
@@ -0,0 +1,16 @@
+/* $Id: dialchk.h,v 1.2 2000/08/26 18:27:17 marekm Exp $ */
+#ifndef _DIALCHK_H_
+#define _DIALCHK_H_
+
+#include "defines.h"
+
+/*
+ * Check for dialup password
+ *
+ * dialcheck tests to see if tty is listed as being a dialup
+ * line. If so, a dialup password may be required if the shell
+ * is listed as one which requires a second password.
+ */
+extern int dialcheck(const char *, const char *);
+
+#endif
diff --git a/current/lib/dialup.c b/current/lib/dialup.c
new file mode 100644
index 00000000..7965c1ae
--- /dev/null
+++ b/current/lib/dialup.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: dialup.c,v 1.3 1997/12/07 23:26:50 marekm Exp $")
+
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "dialup.h"
+
+static FILE *dialpwd;
+
+void
+setduent(void)
+{
+ if (dialpwd)
+ rewind (dialpwd);
+ else
+ dialpwd = fopen (DIALPWD, "r");
+}
+
+void
+endduent(void)
+{
+ if (dialpwd)
+ fclose (dialpwd);
+
+ dialpwd = (FILE *) 0;
+}
+
+struct dialup *
+fgetduent(FILE *fp)
+{
+ static struct dialup dialup; /* static structure to point to */
+ static char sh[128]; /* some space for a login shell */
+ static char passwd[128]; /* some space for dialup password */
+ char buf[BUFSIZ];
+ char *cp;
+ char *cp2;
+
+ if (! fp)
+ return 0;
+
+ if (! fp || feof (fp))
+ return ((struct dialup *) 0);
+
+ while (fgets (buf, sizeof buf, fp) == buf && buf[0] == '#')
+ ;
+
+ if (feof (fp))
+ return ((struct dialup *) 0);
+
+ if ((cp = strchr (buf, '\n')))
+ *cp = '\0';
+
+ if (! (cp = strchr (buf, ':')))
+ return ((struct dialup *) 0);
+
+ if (cp - buf > sizeof sh) /* something is fishy ... */
+ return ((struct dialup *) 0);
+
+ *cp++ = '\0';
+ (void) strcpy (sh, buf);
+ sh[cp - buf] = '\0';
+
+ if ((cp2 = strchr (cp, ':')))
+ *cp2 = '\0';
+
+ if (strlen (cp) + 1 > sizeof passwd) /* something is REALLY fishy */
+ return ((struct dialup *) 0);
+
+ (void) strcpy (passwd, cp);
+
+ dialup.du_shell = sh;
+ dialup.du_passwd = passwd;
+
+ return (&dialup);
+}
+
+struct dialup *
+getduent(void)
+{
+ if (! dialpwd)
+ setduent ();
+
+ return fgetduent (dialpwd);
+}
+
+struct dialup *
+getdushell(const char *sh)
+{
+ struct dialup *dialup;
+
+ while ((dialup = getduent ())) {
+ if (strcmp (sh, dialup->du_shell) == 0)
+ return (dialup);
+
+ if (strcmp (dialup->du_shell, "*") == 0)
+ return (dialup);
+ }
+ return ((struct dialup *) 0);
+}
+
+int
+isadialup(const char *tty)
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+ int dialup = 0;
+
+ if (! (fp = fopen (DIALUPS, "r")))
+ return (0);
+
+ while (fgets (buf, sizeof buf, fp) == buf) {
+ if (buf[0] == '#')
+ continue;
+
+ buf[strlen (buf) - 1] = '\0';
+
+ if (strcmp (buf, tty) == 0) {
+ dialup = 1;
+ break;
+ }
+ }
+ fclose (fp);
+
+ return (dialup);
+}
+
+int
+putduent(const struct dialup *dial, FILE *fp)
+{
+ if (! fp || ! dial)
+ return -1;
+
+ if (fprintf (fp, "%s:%s\n", dial->du_shell, dial->du_passwd) == EOF)
+ return -1;
+
+ return 0;
+}
diff --git a/current/lib/dialup.h b/current/lib/dialup.h
new file mode 100644
index 00000000..2b3892bd
--- /dev/null
+++ b/current/lib/dialup.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Structure of the /etc/d_passwd file
+ *
+ * The d_passwd file contains the names of login shells which require
+ * dialup passwords. Each line contains the fully qualified path name
+ * for the shell, followed by an optional password. Each field is
+ * separated by a ':'.
+ *
+ * Structure of the /etc/dialups file
+ *
+ * The dialups file contains the names of ports which may be dialup
+ * lines. Each line consists of the last component of the path
+ * name. The leading "/dev/" string is removed.
+ *
+ * $Id: dialup.h,v 1.3 2000/08/26 18:27:17 marekm Exp $
+ */
+
+#ifndef _DIALUP_H
+#define _DIALUP_H
+
+struct dialup {
+ char *du_shell;
+ char *du_passwd;
+};
+
+extern void setduent(void);
+extern void endduent(void);
+extern struct dialup *fgetduent(FILE *);
+extern struct dialup *getduent(void);
+extern struct dialup *getdushell(const char *);
+extern int putduent(const struct dialup *, FILE *);
+extern int isadialup(const char *);
+
+#define DIALPWD "/etc/d_passwd"
+#define DIALUPS "/etc/dialups"
+
+#endif
diff --git a/current/lib/encrypt.c b/current/lib/encrypt.c
new file mode 100644
index 00000000..51c16e7a
--- /dev/null
+++ b/current/lib/encrypt.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1990 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: encrypt.c,v 1.7 2000/08/26 18:27:17 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+
+extern char *crypt();
+extern char *libshadow_md5_crypt(const char *, const char *);
+
+char *
+pw_encrypt(const char *clear, const char *salt)
+{
+ static char cipher[128];
+ char *cp;
+#ifdef SW_CRYPT
+ static int count;
+#endif
+
+#ifdef MD5_CRYPT
+ /*
+ * If the salt string from the password file or from crypt_make_salt()
+ * begins with the magic string, use the new algorithm.
+ */
+ if (strncmp(salt, "$1$", 3) == 0)
+ return libshadow_md5_crypt(clear, salt);
+#endif
+
+#ifdef SW_CRYPT
+ /*
+ * Copy over the salt. It is always the first two
+ * characters of the string.
+ */
+
+ cipher[0] = salt[0];
+ cipher[1] = salt[1];
+ cipher[2] = '\0';
+
+ /*
+ * Loop up to ten times on the cleartext password.
+ * This is because the input limit for passwords is
+ * 80 characters.
+ *
+ * The initial salt is that provided by the user, or the
+ * one generated above. The subsequent salts are gotten
+ * from the first two characters of the previous encrypted
+ * block of characters.
+ */
+
+ for (count = 0;count < 10;count++) {
+ cp = crypt(clear, salt);
+ if (!cp) {
+ perror("crypt");
+ exit(1);
+ }
+ if (strlen(cp) != 13)
+ return cp;
+ strcat(cipher, cp + 2);
+ salt = cipher + 11 * count + 2;
+
+ if (strlen(clear) > 8)
+ clear += 8;
+ else
+ break;
+ }
+#else
+ cp = crypt(clear, salt);
+ if (!cp) {
+ /*
+ * Single Unix Spec: crypt() may return a null pointer,
+ * and set errno to indicate an error. The caller doesn't
+ * expect us to return NULL, so...
+ */
+ perror("crypt");
+ exit(1);
+ }
+ if (strlen(cp) != 13)
+ return cp; /* nonstandard crypt() in libc, better bail out */
+ strcpy(cipher, cp);
+
+#ifdef DOUBLESIZE
+ if (strlen (clear) > 8) {
+ cp = crypt(clear + 8, salt);
+ if (!cp) {
+ perror("crypt");
+ exit(1);
+ }
+ strcat(cipher, cp + 2);
+ }
+#endif /* DOUBLESIZE */
+#endif /* SW_CRYPT */
+ return cipher;
+}
diff --git a/current/lib/faillog.h b/current/lib/faillog.h
new file mode 100644
index 00000000..028012c8
--- /dev/null
+++ b/current/lib/faillog.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * faillog.h - login failure logging file format
+ *
+ * $Id: faillog.h,v 1.3 1997/05/01 23:14:39 marekm Exp $
+ *
+ * The login failure file is maintained by login(1) and faillog(8)
+ * Each record in the file represents a separate UID and the file
+ * is indexed in that fashion.
+ */
+
+#ifndef _FAILLOG_H
+#define _FAILLOG_H
+
+struct faillog {
+ short fail_cnt; /* failures since last success */
+ short fail_max; /* failures before turning account off */
+ char fail_line[12]; /* last failure occured here */
+ time_t fail_time; /* last failure occured then */
+ /*
+ * If nonzero, the account will be re-enabled if there are no
+ * failures for fail_locktime seconds since last failure.
+ */
+ long fail_locktime;
+};
+
+#endif
diff --git a/current/lib/fputsx.c b/current/lib/fputsx.c
new file mode 100644
index 00000000..17846110
--- /dev/null
+++ b/current/lib/fputsx.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include "defines.h"
+
+#include "rcsid.h"
+RCSID("$Id: fputsx.c,v 1.5 1999/06/07 16:40:44 marekm Exp $")
+
+char *
+fgetsx(char *buf, int cnt, FILE *f)
+{
+ char *cp = buf;
+ char *ep;
+
+ while (cnt > 0) {
+ if (fgets (cp, cnt, f) == 0) {
+ if (cp == buf)
+ return 0;
+ else
+ break;
+ }
+ if ((ep = strrchr (cp, '\\')) && *(ep + 1) == '\n') {
+ if ((cnt -= ep - cp) > 0)
+ *(cp = ep) = '\0';
+ } else
+ break;
+ }
+ return buf;
+}
+
+int
+fputsx(const char *s, FILE *stream)
+{
+ int i;
+
+ for (i = 0;*s;i++, s++) {
+ if (putc (*s, stream) == EOF)
+ return EOF;
+
+#if 0 /* The standard getgr*() can't handle that. --marekm */
+ if (i > (BUFSIZ/2)) {
+ if (putc ('\\', stream) == EOF ||
+ putc ('\n', stream) == EOF)
+ return EOF;
+
+ i = 0;
+ }
+#endif
+ }
+ return 0;
+}
diff --git a/current/lib/getdef.c b/current/lib/getdef.c
new file mode 100644
index 00000000..12ce99e8
--- /dev/null
+++ b/current/lib/getdef.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: getdef.c,v 1.14 2000/08/26 18:27:17 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include <stdio.h>
+#include <ctype.h>
+#include "getdef.h"
+
+/*
+ * A configuration item definition.
+ */
+
+struct itemdef {
+ const char *name; /* name of the item */
+ char *value; /* value given, or NULL if no value */
+};
+
+/*
+ * This list *must* be sorted by the "name" member.
+ */
+
+#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
+static struct itemdef def_table[] = {
+ { "CHFN_AUTH", NULL },
+ { "CHFN_RESTRICT", NULL },
+#ifdef USE_PAM
+ { "CLOSE_SESSIONS", NULL },
+#endif
+ { "CONSOLE", NULL },
+ { "CONSOLE_GROUPS", NULL },
+ { "CRACKLIB_DICTPATH", NULL },
+ { "CREATE_HOME", NULL },
+ { "DEFAULT_HOME", NULL },
+ { "DIALUPS_CHECK_ENAB", NULL },
+ { "ENVIRON_FILE", NULL },
+ { "ENV_HZ", NULL },
+ { "ENV_PATH", NULL },
+ { "ENV_ROOTPATH", NULL }, /* SuSE compatibility? */
+ { "ENV_SUPATH", NULL },
+ { "ENV_TZ", NULL },
+ { "ERASECHAR", NULL },
+ { "FAILLOG_ENAB", NULL },
+ { "FAIL_DELAY", NULL },
+ { "FAKE_SHELL", NULL },
+ { "FTMP_FILE", NULL },
+ { "GETPASS_ASTERISKS", NULL },
+ { "GID_MAX", NULL },
+ { "GID_MIN", NULL },
+ { "HUSHLOGIN_FILE", NULL },
+ { "ISSUE_FILE", NULL },
+ { "KILLCHAR", NULL },
+ { "LASTLOG_ENAB", NULL },
+ { "LOGIN_RETRIES", NULL },
+ { "LOGIN_STRING", NULL },
+ { "LOGIN_TIMEOUT", NULL },
+ { "LOG_OK_LOGINS", NULL },
+ { "LOG_UNKFAIL_ENAB", NULL },
+ { "MAIL_CHECK_ENAB", NULL },
+ { "MAIL_DIR", NULL },
+ { "MAIL_FILE", NULL },
+ { "MD5_CRYPT_ENAB", NULL },
+ { "MOTD_FILE", NULL },
+ { "NOLOGINS_FILE", NULL },
+ { "NOLOGIN_STR", NULL },
+ { "NO_PASSWORD_CONSOLE", NULL },
+ { "OBSCURE_CHECKS_ENAB", NULL },
+ { "PASS_ALWAYS_WARN", NULL },
+ { "PASS_CHANGE_TRIES", NULL },
+ { "PASS_MAX_DAYS", NULL },
+ { "PASS_MAX_LEN", NULL },
+ { "PASS_MIN_DAYS", NULL },
+ { "PASS_MIN_LEN", NULL },
+ { "PASS_WARN_AGE", NULL },
+ { "PORTTIME_CHECKS_ENAB", NULL },
+ { "QMAIL_DIR", NULL },
+ { "QUOTAS_ENAB", NULL },
+ { "SULOG_FILE", NULL },
+ { "SU_NAME", NULL },
+ { "SU_WHEEL_ONLY", NULL },
+#ifdef USE_SYSLOG
+ { "SYSLOG_SG_ENAB", NULL },
+ { "SYSLOG_SU_ENAB", NULL },
+#endif
+ { "TTYGROUP", NULL },
+ { "TTYPERM", NULL },
+ { "TTYTYPE_FILE", NULL },
+ { "UID_MAX", NULL },
+ { "UID_MIN", NULL },
+ { "ULIMIT", NULL },
+ { "UMASK", NULL },
+ { "USERDEL_CMD", NULL },
+ { "USERGROUPS_ENAB", NULL }
+};
+
+#ifndef LOGINDEFS
+#define LOGINDEFS "/etc/login.defs"
+#endif
+
+static char def_fname[] = LOGINDEFS; /* login config defs file */
+static int def_loaded = 0; /* are defs already loaded? */
+
+extern long strtol();
+
+/* local function prototypes */
+static struct itemdef *def_find(const char *);
+static void def_load(void);
+
+
+/*
+ * getdef_str - get string value from table of definitions.
+ *
+ * Return point to static data for specified item, or NULL if item is not
+ * defined. First time invoked, will load definitions from the file.
+ */
+
+char *
+getdef_str(const char *item)
+{
+ struct itemdef *d;
+
+ if (!def_loaded)
+ def_load();
+
+ return ((d = def_find(item)) == NULL ? (char *)NULL : d->value);
+}
+
+
+/*
+ * getdef_bool - get boolean value from table of definitions.
+ *
+ * Return TRUE if specified item is defined as "yes", else FALSE.
+ */
+
+int
+getdef_bool(const char *item)
+{
+ struct itemdef *d;
+
+ if (!def_loaded)
+ def_load();
+
+ if ((d = def_find(item)) == NULL || d->value == NULL)
+ return 0;
+
+ return (strcasecmp(d->value, "yes") == 0);
+}
+
+
+/*
+ * getdef_num - get numerical value from table of definitions
+ *
+ * Returns numeric value of specified item, else the "dflt" value if
+ * the item is not defined. Octal (leading "0") and hex (leading "0x")
+ * values are handled.
+ */
+
+int
+getdef_num(const char *item, int dflt)
+{
+ struct itemdef *d;
+
+ if (!def_loaded)
+ def_load();
+
+ if ((d = def_find(item)) == NULL || d->value == NULL)
+ return dflt;
+
+ return (int) strtol(d->value, (char **)NULL, 0);
+}
+
+
+/*
+ * getdef_long - get long integer value from table of definitions
+ *
+ * Returns numeric value of specified item, else the "dflt" value if
+ * the item is not defined. Octal (leading "0") and hex (leading "0x")
+ * values are handled.
+ */
+
+long
+getdef_long(const char *item, long dflt)
+{
+ struct itemdef *d;
+
+ if (!def_loaded)
+ def_load();
+
+ if ((d = def_find(item)) == NULL || d->value == NULL)
+ return dflt;
+
+ return strtol(d->value, (char **)NULL, 0);
+}
+
+
+/*
+ * putdef_str - override the value read from /etc/login.defs
+ * (also used when loading the initial defaults)
+ */
+
+int
+putdef_str(const char *name, const char *value)
+{
+ struct itemdef *d;
+ char *cp;
+
+ if (!def_loaded)
+ def_load();
+
+ /*
+ * Locate the slot to save the value. If this parameter
+ * is unknown then "def_find" will print an err message.
+ */
+ if ((d = def_find(name)) == NULL)
+ return -1;
+
+ /*
+ * Save off the value.
+ */
+ if ((cp = strdup(value)) == NULL) {
+ fprintf(stderr,
+ _("Could not allocate space for config info.\n"));
+ SYSLOG((LOG_ERR,
+ "could not allocate space for config info"));
+ return -1;
+ }
+
+ if (d->value)
+ free(d->value);
+
+ d->value = cp;
+ return 0;
+}
+
+
+/*
+ * def_find - locate named item in table
+ *
+ * Search through a sorted table of configurable items to locate the
+ * specified configuration option.
+ */
+
+static struct itemdef *
+def_find(const char *name)
+{
+ int min, max, curr, n;
+
+ /*
+ * Invariant - desired item in range [min:max].
+ */
+
+ min = 0;
+ max = NUMDEFS-1;
+
+ /*
+ * Binary search into the table. Relies on the items being
+ * sorted by name.
+ */
+
+ while (min <= max) {
+ curr = (min+max)/2;
+
+ if (! (n = strcmp(def_table[curr].name, name)))
+ return &def_table[curr];
+
+ if (n < 0)
+ min = curr+1;
+ else
+ max = curr-1;
+ }
+
+ /*
+ * Item was never found.
+ */
+
+ fprintf(stderr, _("configuration error - unknown item '%s' (notify administrator)\n"), name);
+ SYSLOG((LOG_CRIT, "unknown configuration item `%s'", name));
+ return (struct itemdef *) NULL;
+}
+
+/*
+ * def_load - load configuration table
+ *
+ * Loads the user-configured options from the default configuration file
+ */
+
+static void
+def_load(void)
+{
+ int i;
+ FILE *fp;
+ char buf[1024], *name, *value, *s;
+
+ /*
+ * Open the configuration definitions file.
+ */
+ if ((fp = fopen(def_fname, "r")) == NULL) {
+ SYSLOG((LOG_CRIT, "cannot open login definitions %s [%m]",
+ def_fname));
+ return;
+ }
+
+ /*
+ * Set the initialized flag.
+ * (do it early to prevent recursion in putdef_str())
+ */
+ ++def_loaded;
+
+ /*
+ * Go through all of the lines in the file.
+ */
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+
+ /*
+ * Trim trailing whitespace.
+ */
+ for (i = strlen(buf)-1 ; i >= 0 ; --i) {
+ if (!isspace(buf[i]))
+ break;
+ }
+ buf[++i] = '\0';
+
+ /*
+ * Break the line into two fields.
+ */
+ name = buf + strspn(buf, " \t"); /* first nonwhite */
+ if (*name == '\0' || *name == '#')
+ continue; /* comment or empty */
+
+ s = name + strcspn(name, " \t"); /* end of field */
+ if (*s == '\0')
+ continue; /* only 1 field?? */
+
+ *s++ = '\0';
+ value = s + strspn(s, " \"\t"); /* next nonwhite */
+ *(value + strcspn(value, "\"")) = '\0';
+
+ /*
+ * Store the value in def_table.
+ */
+ putdef_str(name, value);
+ }
+ (void) fclose(fp);
+}
+
+
+#ifdef CKDEFS
+int
+main(int argc, char **argv)
+{
+ int i;
+ char *cp;
+ struct itemdef *d;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ def_load ();
+
+ for (i = 0 ; i < NUMDEFS ; ++i) {
+ if ((d = def_find(def_table[i].name)) == NULL)
+ printf(_("error - lookup '%s' failed\n"), def_table[i].name);
+ else
+ printf("%4d %-24s %s\n", i+1, d->name, d->value);
+ }
+ for (i = 1;i < argc;i++) {
+ if ((cp = getdef_str (argv[1])) != NULL)
+ printf ("%s `%s'\n", argv[1], cp);
+ else
+ printf (_("%s not found\n"), argv[1]);
+ }
+ exit(0);
+}
+#endif
diff --git a/current/lib/getdef.h b/current/lib/getdef.h
new file mode 100644
index 00000000..304e1096
--- /dev/null
+++ b/current/lib/getdef.h
@@ -0,0 +1,11 @@
+#ifndef _GETDEF_H
+#define _GETDEF_H
+
+/* getdef.c */
+extern int getdef_bool(const char *);
+extern long getdef_long(const char *, long);
+extern int getdef_num(const char *, int);
+extern char *getdef_str(const char *);
+extern int putdef_str(const char *, const char *);
+
+#endif /* _GETDEF_H */
diff --git a/current/lib/getpass.c b/current/lib/getpass.c
new file mode 100644
index 00000000..cc4b4585
--- /dev/null
+++ b/current/lib/getpass.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright 1990 - 1995, Julianne Frances Haugh
+ * Copyright 1998, Pavel Machek <pavel@ucw.cz>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: getpass.c,v 1.10 1999/08/27 19:02:51 marekm Exp $")
+
+#include "defines.h"
+
+#include <signal.h>
+#include <stdio.h>
+
+#include "getdef.h"
+
+/* new code, #undef if there are any problems... */
+#define USE_SETJMP 1
+
+#ifdef USE_SETJMP
+#include <setjmp.h>
+
+static sigjmp_buf intr; /* where to jump on SIGINT */
+#endif
+
+static int sig_caught;
+#ifdef HAVE_SIGACTION
+static struct sigaction sigact;
+#endif
+
+/*ARGSUSED*/
+static RETSIGTYPE
+sig_catch(int sig)
+{
+ sig_caught = 1;
+#ifdef USE_SETJMP
+ siglongjmp(intr, 1);
+#endif
+}
+
+#define MAXLEN 127
+
+
+static char *
+readpass(FILE *ifp, FILE *ofp, int with_echo, int max_asterisks)
+{
+ static char input[MAXLEN + 1], asterix[MAXLEN + 1];
+ static char once;
+ char *cp, *ap, c;
+ int i;
+
+ if (max_asterisks < 0) {
+ /* traditional code using fgets() */
+ if (fgets(input, sizeof input, ifp) != input)
+ return NULL;
+ cp = strrchr(input, '\n');
+ if (cp)
+ *cp = '\0';
+ else
+ input[sizeof input - 1] = '\0';
+ return input;
+ }
+ if (!once) {
+ srandom(time(0)*getpid());
+ once = 1;
+ }
+ cp = input;
+ ap = asterix;
+ while (read(fileno(ifp), &c, 1)) {
+ switch (c) {
+ case '\n':
+ case '\r':
+ goto endwhile;
+ case '\b':
+ case 127:
+ if (cp > input) {
+ cp--;
+ ap--;
+ for (i = *ap; i > 0; i--)
+ fputs("\b \b", ofp);
+ *cp = '\0';
+ *ap = 0;
+ } else {
+ putc('\a', ofp); /* BEL */
+ }
+ break;
+ case '\025': /* Ctrl-U = erase everything typed so far */
+ if (cp == input) {
+ putc('\a', ofp); /* BEL */
+ } else while (cp > input) {
+ cp--;
+ ap--;
+ for (i = *ap; i > 0; i--)
+ fputs("\b \b", ofp);
+ *cp = '\0';
+ *ap = 0;
+ }
+ break;
+ default:
+ *cp++ = c;
+ if (with_echo) {
+ *ap = 1;
+ putc(c, ofp);
+ } else if (max_asterisks > 0) {
+ *ap = (random() % max_asterisks) + 1;
+ for (i = *ap; i > 0; i--)
+ putc('*', ofp);
+ } else {
+ *ap = 0;
+ }
+ ap++;
+ break;
+ }
+ fflush(ofp);
+ if (cp >= input + MAXLEN) {
+ putc('\a', ofp); /* BEL */
+ break;
+ }
+ }
+endwhile:
+ *cp = '\0';
+ putc('\n', ofp);
+ return input;
+}
+
+static char *
+prompt_password(const char *prompt, int with_echo)
+{
+ static char nostring[1] = "";
+ static char *return_value;
+ volatile int tty_opened;
+ static FILE *ifp, *ofp;
+ volatile int is_tty;
+#ifdef HAVE_SIGACTION
+ struct sigaction old_sigact;
+#else
+ RETSIGTYPE (*old_signal)();
+#endif
+ TERMIO old_modes;
+ int max_asterisks = getdef_num("GETPASS_ASTERISKS", -1);
+
+ /*
+ * set a flag so the SIGINT signal can be re-sent if it
+ * is caught
+ */
+
+ sig_caught = 0;
+ return_value = NULL;
+ tty_opened = 0;
+
+ /*
+ * if /dev/tty can't be opened, getpass() needs to read
+ * from stdin and write to stderr instead.
+ */
+
+ if (!(ifp = fopen("/dev/tty", "r+"))) {
+ ifp = stdin;
+ ofp = stderr;
+ } else {
+ ofp = ifp;
+ tty_opened = 1;
+ }
+ setbuf(ifp, (char *) 0);
+
+ /*
+ * the current tty modes must be saved so they can be
+ * restored later on. echo will be turned off, except
+ * for the newline character
+ */
+
+ is_tty = 1;
+ if (GTTY(fileno(ifp), &old_modes)) {
+ is_tty = 0;
+#if 0 /* to make getpass work with redirected stdin */
+ return_value = NULL;
+ goto out2;
+#endif
+ }
+
+#ifdef USE_SETJMP
+ /*
+ * If we get a SIGINT, sig_catch() will jump here -
+ * no need to press Enter after Ctrl-C.
+ */
+ if (sigsetjmp(intr, 1))
+ goto out;
+#endif
+
+#ifdef HAVE_SIGACTION
+ sigact.sa_handler = sig_catch;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigaction(SIGINT, &sigact, &old_sigact);
+#else
+ old_signal = signal(SIGINT, sig_catch);
+#endif
+
+ if (is_tty) {
+ TERMIO new_modes = old_modes;
+
+ if (max_asterisks < 0)
+ new_modes.c_lflag |= ICANON;
+ else
+ new_modes.c_lflag &= ~(ICANON);
+
+ if (with_echo)
+ new_modes.c_lflag |= (ECHO | ECHOE | ECHOK);
+ else
+ new_modes.c_lflag &= ~(ECHO | ECHOE | ECHOK);
+
+ new_modes.c_lflag |= ECHONL;
+
+ if (STTY(fileno(ifp), &new_modes))
+ goto out;
+ }
+
+ /*
+ * the prompt is output, and the response read without
+ * echoing. the trailing newline must be removed. if
+ * the fgets() returns an error, a NULL pointer is
+ * returned.
+ */
+
+ if ((fputs(prompt, ofp) != EOF) && (fflush(ofp) != EOF))
+ return_value = readpass(ifp, ofp, with_echo, max_asterisks);
+out:
+ /*
+ * the old SIGINT handler is restored after the tty
+ * modes. then /dev/tty is closed if it was opened in
+ * the beginning. finally, if a signal was caught it
+ * is sent to this process for normal processing.
+ */
+
+ if (is_tty) {
+ if (STTY(fileno(ifp), &old_modes))
+ return_value = NULL;
+ }
+
+#ifdef HAVE_SIGACTION
+ (void) sigaction (SIGINT, &old_sigact, NULL);
+#else
+ (void) signal (SIGINT, old_signal);
+#endif
+out2:
+ if (tty_opened)
+ (void) fclose(ifp);
+
+ if (sig_caught) {
+ kill(getpid(), SIGINT);
+ return_value = NULL;
+ }
+ if (!return_value) {
+ nostring[0] = '\0';
+ return_value = nostring;
+ }
+ return return_value;
+}
+
+char *
+libshadow_getpass(const char *prompt)
+{
+ return prompt_password(prompt, 0);
+}
+
+char *
+getpass_with_echo(const char *prompt)
+{
+ return prompt_password(prompt, 1);
+}
+
diff --git a/current/lib/grdbm.c b/current/lib/grdbm.c
new file mode 100644
index 00000000..b08c0f58
--- /dev/null
+++ b/current/lib/grdbm.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef NDBM
+
+#include "rcsid.h"
+RCSID("$Id: grdbm.c,v 1.3 1997/12/07 23:26:52 marekm Exp $")
+
+#include <string.h>
+#include <stdio.h>
+#include <grp.h>
+#include "prototypes.h"
+
+#include <ndbm.h>
+extern DBM *gr_dbm;
+
+#define GRP_FRAG 256
+
+/*
+ * gr_dbm_update
+ *
+ * Updates the DBM password files, if they exist.
+ */
+
+int
+gr_dbm_update(const struct group *gr)
+{
+ datum key;
+ datum content;
+ char data[BUFSIZ*8];
+ char grpkey[60];
+ char *cp;
+ int len;
+ int i;
+ int cnt;
+ static int once;
+
+ if (! once) {
+ if (! gr_dbm)
+ setgrent ();
+
+ once++;
+ }
+ if (! gr_dbm)
+ return 0;
+
+ len = gr_pack (gr, data);
+
+ if (len <= GRP_FRAG) {
+ content.dsize = len;
+ content.dptr = data;
+
+ key.dsize = strlen (gr->gr_name);
+ key.dptr = gr->gr_name;
+ if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ key.dsize = sizeof gr->gr_gid;
+ key.dptr = (char *) &gr->gr_gid;
+ if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ } else {
+ content.dsize = sizeof cnt;
+ content.dptr = (char *) &cnt;
+ cnt = (len + (GRP_FRAG-1)) / GRP_FRAG;
+
+ key.dsize = strlen (gr->gr_name);
+ key.dptr = gr->gr_name;
+ if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ key.dsize = sizeof gr->gr_gid;
+ key.dptr = (char *) &gr->gr_gid;
+ if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ for (cp = data, i = 0;i < cnt;i++) {
+ content.dsize = len > GRP_FRAG ? GRP_FRAG:len;
+ len -= content.dsize;
+ content.dptr = cp;
+ cp += content.dsize;
+
+ key.dsize = sizeof i + strlen (gr->gr_name);
+ key.dptr = grpkey;
+ memcpy (grpkey, (char *) &i, sizeof i);
+ strcpy (grpkey + sizeof i, gr->gr_name);
+ if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ key.dsize = sizeof i + sizeof gr->gr_gid;
+ key.dptr = grpkey;
+ memcpy (grpkey, (char *) &i, sizeof i);
+ memcpy (grpkey + sizeof i, (char *) &gr->gr_gid,
+ sizeof gr->gr_gid);
+ if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * gr_dbm_remove
+ *
+ * Deletes the DBM group file entries, if they exist.
+ */
+
+int
+gr_dbm_remove(const struct group *gr)
+{
+ datum key;
+ datum content;
+ char grpkey[60];
+ int i;
+ int cnt;
+ int errors = 0;
+ static int once;
+
+ if (! once) {
+ if (! gr_dbm)
+ setgrent ();
+
+ once++;
+ }
+ if (! gr_dbm)
+ return 0;
+
+ key.dsize = strlen (gr->gr_name);
+ key.dptr = (char *) gr->gr_name;
+ content = dbm_fetch (gr_dbm, key);
+ if (content.dptr == 0)
+ ++errors;
+ else {
+ if (content.dsize == sizeof (int)) {
+ memcpy ((char *) &cnt, content.dptr, sizeof cnt);
+
+ for (i = 0;i < cnt;i++) {
+ key.dsize = sizeof i + strlen (gr->gr_name);
+ key.dptr = grpkey;
+ memcpy (grpkey, (char *) &i, sizeof i);
+ strcpy (grpkey + sizeof i, gr->gr_name);
+ if (dbm_delete (gr_dbm, key))
+ ++errors;
+ }
+ } else {
+ if (dbm_delete (gr_dbm, key))
+ ++errors;
+ }
+ }
+ key.dsize = sizeof gr->gr_gid;
+ key.dptr = (char *) &gr->gr_gid;
+ content = dbm_fetch (gr_dbm, key);
+ if (content.dptr == 0)
+ ++errors;
+ else {
+ if (content.dsize == sizeof (int)) {
+ memcpy ((char *) &cnt, content.dptr, sizeof cnt);
+
+ for (i = 0;i < cnt;i++) {
+ key.dsize = sizeof i + sizeof gr->gr_gid;
+ key.dptr = grpkey;
+ memcpy (grpkey, (char *) &i, sizeof i);
+ memcpy (grpkey + sizeof i, (char *) &gr->gr_gid,
+ sizeof gr->gr_gid);
+
+ if (dbm_delete (gr_dbm, key))
+ ++errors;
+ }
+ } else {
+ if (dbm_delete (gr_dbm, key))
+ ++errors;
+ }
+ }
+ return errors ? 0:1;
+}
+
+int
+gr_dbm_present(void)
+{
+ return (access(GROUP_PAG_FILE, F_OK) == 0);
+}
+#endif
diff --git a/current/lib/groupio.c b/current/lib/groupio.c
new file mode 100644
index 00000000..a59faadd
--- /dev/null
+++ b/current/lib/groupio.c
@@ -0,0 +1,184 @@
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: groupio.c,v 1.9 2000/09/02 18:40:43 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include "commonio.h"
+#include "groupio.h"
+
+extern int putgrent(const struct group *, FILE *);
+extern struct group *sgetgrent(const char *);
+
+struct group *
+__gr_dup(const struct group *grent)
+{
+ struct group *gr;
+ int i;
+
+ if (!(gr = (struct group *) malloc(sizeof *gr)))
+ return NULL;
+ *gr = *grent;
+ if (!(gr->gr_name = strdup(grent->gr_name)))
+ return NULL;
+ if (!(gr->gr_passwd = strdup(grent->gr_passwd)))
+ return NULL;
+
+ for (i = 0; grent->gr_mem[i]; i++)
+ ;
+ gr->gr_mem = (char **) malloc((i + 1) * sizeof(char *));
+ if (!gr->gr_mem)
+ return NULL;
+ for (i = 0; grent->gr_mem[i]; i++) {
+ gr->gr_mem[i] = strdup(grent->gr_mem[i]);
+ if (!gr->gr_mem[i])
+ return NULL;
+ }
+ gr->gr_mem[i] = NULL;
+ return gr;
+}
+
+static void *
+group_dup(const void *ent)
+{
+ const struct group *gr = ent;
+ return __gr_dup(gr);
+}
+
+static void
+group_free(void *ent)
+{
+ struct group *gr = ent;
+
+ free(gr->gr_name);
+ free(gr->gr_passwd);
+ while(*(gr->gr_mem)) {
+ free(*(gr->gr_mem));
+ gr->gr_mem++;
+ }
+ free(gr);
+}
+
+static const char *
+group_getname(const void *ent)
+{
+ const struct group *gr = ent;
+ return gr->gr_name;
+}
+
+static void *
+group_parse(const char *line)
+{
+ return (void *) sgetgrent(line);
+}
+
+static int
+group_put(const void *ent, FILE *file)
+{
+ const struct group *gr = ent;
+ return (putgrent(gr, file) == -1) ? -1 : 0;
+}
+
+static struct commonio_ops group_ops = {
+ group_dup,
+ group_free,
+ group_getname,
+ group_parse,
+ group_put,
+ fgetsx,
+ fputsx
+};
+
+static struct commonio_db group_db = {
+ GROUP_FILE, /* filename */
+ &group_ops, /* ops */
+ NULL, /* fp */
+ NULL, /* head */
+ NULL, /* tail */
+ NULL, /* cursor */
+ 0, /* changed */
+ 0, /* isopen */
+ 0, /* locked */
+ 0 /* readonly */
+};
+
+int
+gr_name(const char *filename)
+{
+ return commonio_setname(&group_db, filename);
+}
+
+int
+gr_lock(void)
+{
+ return commonio_lock(&group_db);
+}
+
+int
+gr_open(int mode)
+{
+ return commonio_open(&group_db, mode);
+}
+
+const struct group *
+gr_locate(const char *name)
+{
+ return commonio_locate(&group_db, name);
+}
+
+int
+gr_update(const struct group *gr)
+{
+ return commonio_update(&group_db, (const void *) gr);
+}
+
+int
+gr_remove(const char *name)
+{
+ return commonio_remove(&group_db, name);
+}
+
+int
+gr_rewind(void)
+{
+ return commonio_rewind(&group_db);
+}
+
+const struct group *
+gr_next(void)
+{
+ return commonio_next(&group_db);
+}
+
+int
+gr_close(void)
+{
+ return commonio_close(&group_db);
+}
+
+int
+gr_unlock(void)
+{
+ return commonio_unlock(&group_db);
+}
+
+void
+__gr_set_changed(void)
+{
+ group_db.changed = 1;
+}
+
+struct commonio_entry *
+__gr_get_head(void)
+{
+ return group_db.head;
+}
+
+void
+__gr_del_entry(const struct commonio_entry *ent)
+{
+ commonio_del_entry(&group_db, ent);
+}
diff --git a/current/lib/groupio.h b/current/lib/groupio.h
new file mode 100644
index 00000000..7c083cea
--- /dev/null
+++ b/current/lib/groupio.h
@@ -0,0 +1,12 @@
+extern struct group *__gr_dup(const struct group *);
+extern void __gr_set_changed(void);
+extern int gr_close(void);
+extern const struct group *gr_locate(const char *);
+extern int gr_lock(void);
+extern int gr_name(const char *);
+extern const struct group *gr_next(void);
+extern int gr_open(int);
+extern int gr_remove(const char *);
+extern int gr_rewind(void);
+extern int gr_unlock(void);
+extern int gr_update(const struct group *);
diff --git a/current/lib/grpack.c b/current/lib/grpack.c
new file mode 100644
index 00000000..9f4a1803
--- /dev/null
+++ b/current/lib/grpack.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1990, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: grpack.c,v 1.3 1997/12/07 23:26:52 marekm Exp $")
+
+#include <stdio.h>
+#include <grp.h>
+
+#include "defines.h"
+
+int
+gr_pack(const struct group *group, char *buf)
+{
+ char *cp;
+ int i;
+
+ cp = buf;
+ strcpy (cp, group->gr_name);
+ cp += strlen (cp) + 1;
+
+ strcpy (cp, group->gr_passwd);
+ cp += strlen (cp) + 1;
+
+ memcpy (cp, (const char *) &group->gr_gid, sizeof group->gr_gid);
+ cp += sizeof group->gr_gid;
+
+ for (i = 0;group->gr_mem[i];i++) {
+ strcpy (cp, group->gr_mem[i]);
+ cp += strlen (cp) + 1;
+ }
+ *cp++ = '\0';
+
+ return cp - buf;
+}
+
+int
+gr_unpack(char *buf, int len, struct group *group)
+{
+ char *org = buf;
+ int i;
+
+ group->gr_name = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ group->gr_passwd = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ memcpy ((char *) &group->gr_gid, (char *) buf, sizeof group->gr_gid);
+ buf += sizeof group->gr_gid;
+ if (buf - org > len)
+ return -1;
+
+ for (i = 0;*buf && i < 1024;i++) {
+ group->gr_mem[i] = buf;
+ buf += strlen (buf) + 1;
+
+ if (buf - org > len)
+ return -1;
+ }
+ group->gr_mem[i] = (char *) 0;
+ return 0;
+}
diff --git a/current/lib/gsdbm.c b/current/lib/gsdbm.c
new file mode 100644
index 00000000..a6da67ae
--- /dev/null
+++ b/current/lib/gsdbm.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#if defined(NDBM) && defined(SHADOWGRP) /*{*/
+
+#include <string.h>
+#include <stdio.h>
+#include "prototypes.h"
+
+#include "rcsid.h"
+RCSID("$Id: gsdbm.c,v 1.3 1997/12/07 23:26:53 marekm Exp $")
+
+#include <ndbm.h>
+extern DBM *sg_dbm;
+
+#define GRP_FRAG 256
+
+/*
+ * sg_dbm_update
+ *
+ * Updates the DBM password files, if they exist.
+ */
+
+int
+sg_dbm_update(const struct sgrp *sgr)
+{
+ datum key;
+ datum content;
+ char data[BUFSIZ*8];
+ char sgrpkey[60];
+ char *cp;
+ int len;
+ int i;
+ int cnt;
+ static int once;
+
+ if (! once) {
+ if (! sg_dbm)
+ setsgent ();
+
+ once++;
+ }
+ if (! sg_dbm)
+ return 0;
+
+ len = sgr_pack (sgr, data);
+
+ if (len <= GRP_FRAG) {
+ content.dsize = len;
+ content.dptr = data;
+
+ key.dsize = strlen (sgr->sg_name);
+ key.dptr = sgr->sg_name;
+ if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
+ return 0;
+ } else {
+ content.dsize = sizeof cnt;
+ content.dptr = (char *) &cnt;
+ cnt = (len + (GRP_FRAG-1)) / GRP_FRAG;
+
+ key.dsize = strlen (sgr->sg_name);
+ key.dptr = sgr->sg_name;
+ if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ for (cp = data, i = 0;i < cnt;i++) {
+ content.dsize = len > GRP_FRAG ? GRP_FRAG:len;
+ len -= content.dsize;
+ content.dptr = cp;
+ cp += content.dsize;
+
+ key.dsize = sizeof i + strlen (sgr->sg_name);
+ key.dptr = sgrpkey;
+ memcpy (sgrpkey, (char *) &i, sizeof i);
+ strcpy (sgrpkey + sizeof i, sgr->sg_name);
+ if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * sg_dbm_remove
+ *
+ * Deletes the DBM shadow group file entries, if they exist.
+ */
+
+int
+sg_dbm_remove(const char *name)
+{
+ datum key;
+ datum content;
+ char grpkey[60];
+ int i;
+ int cnt;
+ int errors = 0;
+ static int once;
+
+ if (! once) {
+ if (! sg_dbm)
+ setsgent ();
+
+ once++;
+ }
+ if (! sg_dbm)
+ return 0;
+
+ key.dsize = strlen (name);
+ key.dptr = name;
+ content = dbm_fetch (sg_dbm, key);
+ if (content.dptr == 0)
+ ++errors;
+ else {
+ if (content.dsize == sizeof (int)) {
+ memcpy ((char *) &cnt, content.dptr, sizeof cnt);
+
+ for (i = 0;i < cnt;i++) {
+ key.dsize = sizeof i + strlen (name);
+ key.dptr = grpkey;
+ memcpy (grpkey, (char *) &i, sizeof i);
+ strcpy (grpkey + sizeof i, name);
+ if (dbm_delete (sg_dbm, key))
+ ++errors;
+ }
+ } else {
+ if (dbm_delete (sg_dbm, key))
+ ++errors;
+ }
+ }
+ return errors ? 0:1;
+}
+
+int
+sg_dbm_present(void)
+{
+ return (access(SGROUP_PAG_FILE, F_OK) == 0);
+}
+#endif /*} SHADOWGRP && NDBM */
diff --git a/current/lib/gshadow.c b/current/lib/gshadow.c
new file mode 100644
index 00000000..8de925b8
--- /dev/null
+++ b/current/lib/gshadow.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+/* Newer versions of Linux libc already have shadow support. */
+#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: gshadow.c,v 1.6 1998/04/02 21:51:43 marekm Exp $")
+
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#ifdef NDBM
+#include <ndbm.h>
+#include <fcntl.h>
+DBM *sg_dbm;
+int sg_dbm_mode = -1;
+static int dbmopened;
+static int dbmerror;
+#endif
+
+#define MAXMEM 1024
+
+static FILE *shadow;
+static char sgrbuf[BUFSIZ*4];
+static char *members[MAXMEM+1];
+static char *admins[MAXMEM+1];
+static struct sgrp sgroup;
+
+extern char *fgetsx();
+extern int fputsx();
+
+#define FIELDS 4
+
+#ifdef USE_NIS
+static int nis_used;
+static int nis_ignore;
+static enum { native, start, middle, native2 } nis_state;
+static int nis_bound;
+static char *nis_domain;
+static char *nis_key;
+static int nis_keylen;
+static char *nis_val;
+static int nis_vallen;
+#define IS_NISCHAR(c) ((c)=='+')
+#endif
+
+#ifdef USE_NIS
+
+/*
+ * __setsgNIS - turn on or off NIS searches
+ */
+
+void
+__setsgNIS(int flag)
+{
+ nis_ignore = ! flag;
+
+ if (nis_ignore)
+ nis_used = 0;
+}
+
+/*
+ * bind_nis - bind to NIS server
+ */
+
+static int
+bind_nis(void)
+{
+ if (yp_get_default_domain (&nis_domain))
+ return -1;
+
+ nis_bound = 1;
+ return 0;
+}
+#endif
+
+static char **
+list(char *s, char **l)
+{
+ int nmembers = 0;
+
+ while (s && *s) {
+ l[nmembers++] = s;
+ if ((s = strchr (s, ',')))
+ *s++ = '\0';
+ }
+ l[nmembers] = (char *) 0;
+ return l;
+}
+
+void
+setsgent(void)
+{
+#ifdef NDBM
+ int mode;
+#endif /* NDBM */
+
+#ifdef USE_NIS
+ nis_state = native;
+#endif
+ if (shadow)
+ rewind (shadow);
+ else
+ shadow = fopen(SGROUP_FILE, "r");
+
+ /*
+ * Attempt to open the DBM files if they have never been opened
+ * and an error has never been returned.
+ */
+
+#ifdef NDBM
+ if (! dbmerror && ! dbmopened) {
+ char dbmfiles[BUFSIZ];
+
+ strcpy (dbmfiles, SGROUP_PAG_FILE);
+
+ if (sg_dbm_mode == -1)
+ mode = O_RDWR;
+ else
+ mode = (sg_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY;
+
+ if (access(dbmfiles, F_OK) ||
+ (! (sg_dbm = dbm_open(SGROUP_FILE, mode, 0))))
+ dbmerror = 1;
+ else
+ dbmopened = 1;
+ }
+#endif /* NDBM */
+}
+
+void
+endsgent(void)
+{
+ if (shadow)
+ (void) fclose (shadow);
+
+ shadow = (FILE *) 0;
+#ifdef NDBM
+ if (dbmopened && sg_dbm) {
+ dbm_close (sg_dbm);
+ dbmopened = 0;
+ sg_dbm = 0;
+ }
+#endif
+}
+
+struct sgrp *
+sgetsgent(const char *string)
+{
+ char *fields[FIELDS];
+ char *cp;
+ int i;
+
+ strncpy (sgrbuf, string, (int) sizeof sgrbuf - 1);
+ sgrbuf[sizeof sgrbuf - 1] = '\0';
+
+ if ((cp = strrchr (sgrbuf, '\n')))
+ *cp = '\0';
+
+ /*
+ * There should be exactly 4 colon separated fields. Find
+ * all 4 of them and save the starting addresses in fields[].
+ */
+
+ for (cp = sgrbuf, i = 0;i < FIELDS && cp;i++) {
+ fields[i] = cp;
+ if ((cp = strchr (cp, ':')))
+ *cp++ = '\0';
+ }
+
+ /*
+ * If there was an extra field somehow, or perhaps not enough,
+ * the line is invalid.
+ */
+
+ if (cp || i != FIELDS)
+#ifdef USE_NIS
+ if (! IS_NISCHAR (fields[0][0]))
+ return 0;
+ else
+ nis_used = 1;
+#else
+ return 0;
+#endif
+
+ sgroup.sg_name = fields[0];
+ sgroup.sg_passwd = fields[1];
+ sgroup.sg_adm = list (fields[2], admins);
+ sgroup.sg_mem = list (fields[3], members);
+
+ return &sgroup;
+}
+
+/*
+ * fgetsgent - convert next line in stream to (struct sgrp)
+ *
+ * fgetsgent() reads the next line from the provided stream and
+ * converts it to a (struct sgrp). NULL is returned on EOF.
+ */
+
+struct sgrp *
+fgetsgent(FILE *fp)
+{
+ char buf[sizeof sgrbuf];
+ char *cp;
+
+ if (! fp)
+ return (0);
+
+#ifdef USE_NIS
+ while (fgetsx (buf, sizeof buf, fp) != (char *) 0)
+#else
+ if (fgetsx (buf, sizeof buf, fp) != (char *) 0)
+#endif
+ {
+ if ((cp = strchr (buf, '\n')))
+ *cp = '\0';
+#ifdef USE_NIS
+ if (nis_ignore && IS_NISCHAR (buf[0]))
+ continue;
+#endif
+ return (sgetsgent (buf));
+ }
+ return 0;
+}
+
+/*
+ * getsgent - get a single shadow group entry
+ */
+
+struct sgrp *
+getsgent(void)
+{
+#ifdef USE_NIS
+ int nis_1_group = 0;
+ struct sgrp *val;
+ char buf[BUFSIZ];
+#endif
+ if (! shadow)
+ setsgent ();
+
+#ifdef USE_NIS
+again:
+ /*
+ * See if we are reading from the local file.
+ */
+
+ if (nis_state == native || nis_state == native2) {
+
+ /*
+ * Get the next entry from the shadow group file. Return
+ * NULL right away if there is none.
+ */
+
+ if (! (val = fgetsgent (shadow)))
+ return 0;
+
+ /*
+ * If this entry began with a NIS escape character, we have
+ * to see if this is just a single group, or if the entire
+ * map is being asked for.
+ */
+
+ if (IS_NISCHAR (val->sg_name[0])) {
+ if (val->sg_name[1])
+ nis_1_group = 1;
+ else
+ nis_state = start;
+ }
+
+ /*
+ * If this isn't a NIS group and this isn't an escape to go
+ * use a NIS map, it must be a regular local group.
+ */
+
+ if (nis_1_group == 0 && nis_state != start)
+ return val;
+
+ /*
+ * If this is an escape to use an NIS map, switch over to
+ * that bunch of code.
+ */
+
+ if (nis_state == start)
+ goto again;
+
+ /*
+ * NEEDSWORK. Here we substitute pieces-parts of this entry.
+ */
+
+ return 0;
+ } else {
+ if (nis_bound == 0) {
+ if (bind_nis ()) {
+ nis_state = native2;
+ goto again;
+ }
+ }
+ if (nis_state == start) {
+ if (yp_first (nis_domain, "gshadow.byname", &nis_key,
+ &nis_keylen, &nis_val, &nis_vallen)) {
+ nis_state = native2;
+ goto again;
+ }
+ nis_state = middle;
+ } else if (nis_state == middle) {
+ if (yp_next (nis_domain, "gshadow.byname", nis_key,
+ nis_keylen, &nis_key, &nis_keylen,
+ &nis_val, &nis_vallen)) {
+ nis_state = native2;
+ goto again;
+ }
+ }
+ return sgetsgent (nis_val);
+ }
+#else
+ return (fgetsgent (shadow));
+#endif
+}
+
+/*
+ * getsgnam - get a shadow group entry by name
+ */
+
+struct sgrp *
+getsgnam(const char *name)
+{
+ struct sgrp *sgrp;
+#ifdef NDBM
+ datum key;
+ datum content;
+#endif
+#ifdef USE_NIS
+ char buf[BUFSIZ];
+ static char save_name[16];
+ int nis_disabled = 0;
+#endif
+
+ setsgent ();
+
+#ifdef NDBM
+
+ /*
+ * If the DBM file are now open, create a key for this group and
+ * try to fetch the entry from the database. A matching record
+ * will be unpacked into a static structure and returned to
+ * the user.
+ */
+
+ if (dbmopened) {
+ key.dsize = strlen (name);
+ key.dptr = (void *) name;
+
+ content = dbm_fetch (sg_dbm, key);
+ if (content.dptr != 0) {
+ memcpy (sgrbuf, content.dptr, content.dsize);
+ sgroup.sg_mem = members;
+ sgroup.sg_adm = admins;
+ sgr_unpack (sgrbuf, content.dsize, &sgroup);
+ return &sgroup;
+ }
+ }
+#endif
+#ifdef USE_NIS
+ if (nis_used) {
+again:
+
+ /*
+ * Search the gshadow.byname map for this group.
+ */
+
+ if (! nis_bound)
+ bind_nis ();
+
+ if (nis_bound) {
+ char *cp;
+
+ if (yp_match (nis_domain, "gshadow.byname", name,
+ strlen (name), &nis_val, &nis_vallen) == 0) {
+ if (cp = strchr (nis_val, '\n'))
+ *cp = '\0';
+
+ nis_state = middle;
+ if (sgrp = sgetsgent (nis_val)) {
+ strcpy (save_name, sgrp->sg_name);
+ nis_key = save_name;
+ nis_keylen = strlen (save_name);
+ }
+ return sgrp;
+ }
+ }
+ nis_state = native2;
+ }
+#endif
+#ifdef USE_NIS
+ if (nis_used) {
+ nis_ignore++;
+ nis_disabled++;
+ }
+#endif
+ while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
+ if (strcmp (name, sgrp->sg_name) == 0)
+ break;
+ }
+#ifdef USE_NIS
+ nis_ignore--;
+#endif
+ if (sgrp)
+ return sgrp;
+ return (0);
+}
+
+/*
+ * putsgent - output shadow group entry in text form
+ *
+ * putsgent() converts the contents of a (struct sgrp) to text and
+ * writes the result to the given stream. This is the logical
+ * opposite of fgetsgent.
+ */
+
+int
+putsgent(const struct sgrp *sgrp, FILE *fp)
+{
+ char *buf, *cp;
+ int i;
+ size_t size;
+
+ if (! fp || ! sgrp)
+ return -1;
+
+ /* calculate the required buffer size */
+ size = strlen(sgrp->sg_name) + strlen(sgrp->sg_passwd) + 10;
+ for (i = 0; sgrp->sg_adm && sgrp->sg_adm[i]; i++)
+ size += strlen(sgrp->sg_adm[i]) + 1;
+ for (i = 0; sgrp->sg_mem && sgrp->sg_mem[i]; i++)
+ size += strlen(sgrp->sg_mem[i]) + 1;
+
+ buf = malloc(size);
+ if (!buf)
+ return -1;
+ cp = buf;
+
+ /*
+ * Copy the group name and passwd.
+ */
+
+ strcpy (cp, sgrp->sg_name);
+ cp += strlen (cp);
+ *cp++ = ':';
+
+ strcpy (cp, sgrp->sg_passwd);
+ cp += strlen (cp);
+ *cp++ = ':';
+
+ /*
+ * Copy the administrators, separating each from the other
+ * with a ",".
+ */
+
+ for (i = 0;sgrp->sg_adm[i];i++) {
+ if (i > 0)
+ *cp++ = ',';
+
+ strcpy (cp, sgrp->sg_adm[i]);
+ cp += strlen (cp);
+ }
+ *cp++ = ':';
+
+ /*
+ * Now do likewise with the group members.
+ */
+
+ for (i = 0;sgrp->sg_mem[i];i++) {
+ if (i > 0)
+ *cp++ = ',';
+
+ strcpy (cp, sgrp->sg_mem[i]);
+ cp += strlen (cp);
+ }
+ *cp++ = '\n';
+ *cp = '\0';
+
+ /*
+ * Output using the function which understands the line
+ * continuation conventions.
+ */
+
+ if (fputsx(buf, fp) == EOF) {
+ free(buf);
+ return -1;
+ }
+
+ free(buf);
+ return 0;
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif /*} SHADOWGRP */
diff --git a/current/lib/gshadow_.h b/current/lib/gshadow_.h
new file mode 100644
index 00000000..b1cac557
--- /dev/null
+++ b/current/lib/gshadow_.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1988 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: gshadow_.h,v 1.2 1997/05/01 23:14:41 marekm Exp $
+ */
+
+#ifndef _H_GSHADOW
+#define _H_GSHADOW
+
+/*
+ * Shadow group security file structure
+ */
+
+struct sgrp {
+ char *sg_name; /* group name */
+ char *sg_passwd; /* group password */
+ char **sg_adm; /* group administator list */
+ char **sg_mem; /* group membership list */
+};
+
+/*
+ * Shadow group security file functions.
+ */
+
+#include <stdio.h> /* for FILE */
+
+#if __STDC__
+struct sgrp *getsgent (void);
+struct sgrp *getsgnam (const char *);
+struct sgrp *sgetsgent (const char *);
+struct sgrp *fgetsgent (FILE *);
+void setsgent (void);
+void endsgent (void);
+int putsgent (const struct sgrp *, FILE *);
+#else
+struct sgrp *getsgent ();
+struct sgrp *getsgnam ();
+struct sgrp *sgetsgent ();
+struct sgrp *fgetsgent ();
+void setsgent ();
+void endsgent ();
+int putsgent ();
+#endif
+
+#define GSHADOW "/etc/gshadow"
+#endif /* ifndef _H_GSHADOW */
diff --git a/current/lib/gspack.c b/current/lib/gspack.c
new file mode 100644
index 00000000..fe76060b
--- /dev/null
+++ b/current/lib/gspack.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef SHADOWGRP /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: gspack.c,v 1.3 1997/12/07 23:26:53 marekm Exp $")
+
+#include <stdio.h>
+#include "defines.h"
+
+/*
+ * sgr_pack - convert a shadow group structure to a packed
+ * shadow group record
+ *
+ * sgr_pack takes the shadow group structure and packs
+ * the components in a record. this record will be
+ * unpacked later by sgr_unpack.
+ */
+
+int
+sgr_pack(const struct sgrp *sgrp, char *buf)
+{
+ char *cp;
+ int i;
+
+ /*
+ * The name and password are both easy - append each string
+ * to the buffer. These are always the first two strings
+ * in a record.
+ */
+
+ cp = buf;
+ strcpy (cp, sgrp->sg_name);
+ cp += strlen (cp) + 1;
+
+ strcpy (cp, sgrp->sg_passwd);
+ cp += strlen (cp) + 1;
+
+ /*
+ * The arrays of administrators and members are slightly
+ * harder. Each element is appended as a string, with a
+ * final '\0' appended to serve as a blank string. The
+ * number of elements is not known in advance, so the
+ * entire collection of administrators must be scanned to
+ * find the start of the members.
+ */
+
+ for (i = 0;sgrp->sg_adm[i];i++) {
+ strcpy (cp, sgrp->sg_adm[i]);
+ cp += strlen (cp) + 1;
+ }
+ *cp++ = '\0';
+
+ for (i = 0;sgrp->sg_mem[i];i++) {
+ strcpy (cp, sgrp->sg_mem[i]);
+ cp += strlen (cp) + 1;
+ }
+ *cp++ = '\0';
+
+ return cp - buf;
+}
+
+/*
+ * sgr_unpack - convert a packed shadow group record to an
+ * unpacked record
+ *
+ * sgr_unpack converts a record which was packed by sgr_pack
+ * into the normal shadow group structure format.
+ */
+
+int
+sgr_unpack(char *buf, int len, struct sgrp *sgrp)
+{
+ char *org = buf;
+ int i;
+
+ /*
+ * The name and password are both easy - they are the first
+ * two strings in the record.
+ */
+
+ sgrp->sg_name = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ sgrp->sg_passwd = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ /*
+ * The administrators and members are slightly more difficult.
+ * The arrays are lists of strings. Each list is terminated
+ * by a string of length zero. This string is detected by
+ * looking for an initial character of '\0'.
+ */
+
+ for (i = 0;*buf && i < 1024;i++) {
+ sgrp->sg_adm[i] = buf;
+ buf += strlen (buf) + 1;
+
+ if (buf - org > len)
+ return -1;
+ }
+ sgrp->sg_adm[i] = (char *) 0;
+ if (! *buf)
+ buf++;
+
+ for (i = 0;*buf && i < 1024;i++) {
+ sgrp->sg_mem[i] = buf;
+ buf += strlen (buf) + 1;
+
+ if (buf - org > len)
+ return -1;
+ }
+ sgrp->sg_mem[i] = (char *) 0;
+
+ return 0;
+}
+#endif /*}*/
diff --git a/current/lib/lastlog_.h b/current/lib/lastlog_.h
new file mode 100644
index 00000000..8d459de6
--- /dev/null
+++ b/current/lib/lastlog_.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * lastlog.h - structure of lastlog file
+ *
+ * $Id: lastlog_.h,v 1.2 1997/05/01 23:14:42 marekm Exp $
+ *
+ * This file defines a lastlog file structure which should be sufficient
+ * to hold the information required by login. It should only be used if
+ * there is no real lastlog.h file.
+ */
+
+#ifndef __LASTLOG_H
+#define __LASTLOG_H
+
+struct lastlog {
+ time_t ll_time;
+ char ll_line[12];
+ char ll_host[16];
+};
+
+#define HAVE_LL_HOST
+#endif /* _LASTLOG_H */
diff --git a/current/lib/lockpw.c b/current/lib/lockpw.c
new file mode 100644
index 00000000..879dc983
--- /dev/null
+++ b/current/lib/lockpw.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1992, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_LCKPWDF
+
+#include "rcsid.h"
+RCSID("$Id: lockpw.c,v 1.4 1998/01/29 23:22:28 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include "pwio.h"
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+
+/*
+ * lckpwdf - lock the password files
+ */
+
+int
+lckpwdf(void)
+{
+ int i;
+
+ /*
+ * We have 15 seconds to lock the whole mess
+ */
+
+ for (i = 0;i < 15;i++)
+ if (pw_lock ())
+ break;
+ else
+ sleep (1);
+
+ /*
+ * Did we run out of time?
+ */
+
+ if (i == 15)
+ return -1;
+
+ /*
+ * Nope, use any remaining time to lock the shadow password
+ * file.
+ */
+
+ for (;i < 15;i++)
+ if (spw_lock ())
+ break;
+ else
+ sleep (1);
+
+ /*
+ * Out of time yet?
+ */
+
+ if (i == 15) {
+ pw_unlock ();
+ return -1;
+ }
+
+ /*
+ * Nope - and both files are now locked.
+ */
+
+ return 0;
+}
+
+/*
+ * ulckpwdf - unlock the password files
+ */
+
+int
+ulckpwdf(void)
+{
+
+ /*
+ * Unlock both files.
+ */
+
+ return (pw_unlock () && spw_unlock ()) ? 0:-1;
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif
diff --git a/current/lib/md5.c b/current/lib/md5.c
new file mode 100644
index 00000000..766fafe8
--- /dev/null
+++ b/current/lib/md5.c
@@ -0,0 +1,261 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+#include <config.h>
+
+#ifdef MD5_CRYPT
+#include <string.h> /* for memcpy() */
+#include "md5.h"
+
+#ifndef HIGHFIRST
+#define byteReverse(buf, len) /* Nothing */
+#else
+void byteReverse(unsigned char *buf, unsigned longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+void
+byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32 *) ctx->in)[14] = ctx->bits[0];
+ ((uint32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
+#endif /* MD5_CRYPT */
diff --git a/current/lib/md5.h b/current/lib/md5.h
new file mode 100644
index 00000000..e264f686
--- /dev/null
+++ b/current/lib/md5.h
@@ -0,0 +1,27 @@
+#ifndef MD5_H
+#define MD5_H
+
+#ifdef __alpha
+typedef unsigned int uint32;
+#else
+typedef unsigned long uint32;
+#endif
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, unsigned char const *buf,
+ unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+void MD5Transform(uint32 buf[4], uint32 const in[16]);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+typedef struct MD5Context MD5_CTX;
+
+#endif /* !MD5_H */
diff --git a/current/lib/md5crypt.c b/current/lib/md5crypt.c
new file mode 100644
index 00000000..e1595aa2
--- /dev/null
+++ b/current/lib/md5crypt.c
@@ -0,0 +1,151 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * Ported from FreeBSD to Linux, only minimal changes. --marekm
+ */
+
+#include <config.h>
+
+#ifdef MD5_CRYPT
+
+#include "rcsid.h"
+RCSID("$Id: md5crypt.c,v 1.3 1998/01/29 23:22:29 marekm Exp $")
+
+#include <unistd.h>
+/* #include <stdio.h> */
+#include <string.h>
+#include "md5.h"
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void
+to64(char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+
+char *
+libshadow_md5_crypt(const char *pw, const char *salt)
+{
+ static char *magic = "$1$"; /*
+ * This string is magic for
+ * this algorithm. Having
+ * it this way, we can get
+ * get better later on
+ */
+ static char passwd[120], *p;
+ static const char *sp,*ep;
+ unsigned char final[16];
+ int sl,pl,i,j;
+ MD5_CTX ctx,ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if(!strncmp(sp,magic,strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Update(&ctx,pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Update(&ctx,magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Update(&ctx,sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Init(&ctx1);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Update(&ctx1,sp,sl);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ for(pl = strlen(pw); pl > 0; pl -= 16)
+ MD5Update(&ctx,final,pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ /* Then something really weird... */
+ for (j=0,i = strlen(pw); i ; i >>= 1)
+ if(i&1)
+ MD5Update(&ctx, final+j, 1);
+ else
+ MD5Update(&ctx, pw+j, 1);
+
+ /* Now make the output string */
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
+
+ MD5Final(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for(i=0;i<1000;i++) {
+ MD5Init(&ctx1);
+ if(i & 1)
+ MD5Update(&ctx1,pw,strlen(pw));
+ else
+ MD5Update(&ctx1,final,16);
+
+ if(i % 3)
+ MD5Update(&ctx1,sp,sl);
+
+ if(i % 7)
+ MD5Update(&ctx1,pw,strlen(pw));
+
+ if(i & 1)
+ MD5Update(&ctx1,final,16);
+ else
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
+ l = final[11] ; to64(p,l,2); p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ return passwd;
+}
+#endif
diff --git a/current/lib/mkdir.c b/current/lib/mkdir.c
new file mode 100644
index 00000000..9e26b22a
--- /dev/null
+++ b/current/lib/mkdir.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <fcntl.h>
+
+#include "rcsid.h"
+RCSID("$Id: mkdir.c,v 1.4 1998/01/29 23:22:30 marekm Exp $")
+
+/*
+ * mkdir - create a directory
+ *
+ * mkdir is provided for systems which do not include the mkdir()
+ * system call.
+ */
+
+int
+mkdir(const char *dir, int mode)
+{
+ int status;
+
+ if (fork()) {
+ while (wait(&status) != -1)
+ ;
+
+ return status >> 8;
+ }
+ close(2);
+ open("/dev/null", O_WRONLY);
+ umask(0777 & ~ mode);
+ execl("/bin/mkdir", "mkdir", dir, 0);
+ _exit(127);
+ /*NOTREACHED*/
+}
diff --git a/current/lib/pam_defs.h b/current/lib/pam_defs.h
new file mode 100644
index 00000000..58d25c5c
--- /dev/null
+++ b/current/lib/pam_defs.h
@@ -0,0 +1,21 @@
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+
+/* compatibility with different versions of Linux-PAM */
+#ifndef PAM_ESTABLISH_CRED
+#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH
+#endif
+#ifndef PAM_DELETE_CRED
+#define PAM_DELETE_CRED PAM_CRED_DELETE
+#endif
+#ifndef PAM_NEW_AUTHTOK_REQD
+#define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD
+#endif
+#ifndef PAM_DATA_SILENT
+#define PAM_DATA_SILENT 0
+#endif
+#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
+#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
+#else
+#define PAM_STRERROR(pamh, err) pam_strerror(err)
+#endif
diff --git a/current/lib/port.c b/current/lib/port.c
new file mode 100644
index 00000000..6ffb9125
--- /dev/null
+++ b/current/lib/port.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: port.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include "defines.h"
+#include "port.h"
+
+extern int errno;
+
+static FILE *ports;
+
+/*
+ * portcmp - compare the name of a port to a /etc/porttime entry
+ *
+ * portcmp works like strcmp, except that if the last character
+ * in a failing match is a '*', the match is considered to have
+ * passed. The "*" match is suppressed whenever the port is "SU",
+ * which is the token the "su" command uses to validate access.
+ * A match returns 0, failure returns non-zero.
+ */
+
+static int
+portcmp(const char *pattern, const char *port)
+{
+ const char *orig = port;
+
+ while (*pattern && *pattern == *port)
+ pattern++, port++;
+
+ if (*pattern == 0 && *port == 0)
+ return 0;
+ if (orig[0] == 'S' && orig[1] == 'U' && orig[2] == '\0')
+ return 1;
+
+ return *pattern == '*' ? 0:1;
+}
+
+/*
+ * setportent - open /etc/porttime file or rewind
+ *
+ * the /etc/porttime file is rewound if already open, or
+ * opened for reading.
+ */
+
+static void
+setportent(void)
+{
+ if (ports)
+ rewind (ports);
+ else
+ ports = fopen (PORTS, "r");
+}
+
+/*
+ * endportent - close the /etc/porttime file
+ *
+ * the /etc/porttime file is closed and the ports variable set
+ * to NULL to indicate that the /etc/porttime file is no longer
+ * open.
+ */
+
+static void
+endportent(void)
+{
+ if (ports)
+ fclose (ports);
+
+ ports = (FILE *) 0;
+}
+
+/*
+ * getportent - read a single entry from /etc/porttime
+ *
+ * the next line in /etc/porttime is converted to a (struct port)
+ * and a pointer to a static (struct port) is returned to the
+ * invoker. NULL is returned on either EOF or error. errno is
+ * set to EINVAL on error to distinguish the two conditions.
+ */
+
+static struct port *
+getportent(void)
+{
+ static struct port port; /* static struct to point to */
+ static char buf[BUFSIZ]; /* some space for stuff */
+ static char *ttys[PORT_TTY+1]; /* some pointers to tty names */
+ static char *users[PORT_IDS+1]; /* some pointers to user ids */
+ static struct pt_time ptimes[PORT_TIMES+1]; /* time ranges */
+ char *cp; /* pointer into line */
+ int dtime; /* scratch time of day */
+ int i, j;
+ int saveerr = errno; /* errno value on entry */
+
+ /*
+ * If the ports file is not open, open the file. Do not rewind
+ * since we want to search from the beginning each time.
+ */
+
+ if (! ports)
+ setportent ();
+
+ if (! ports) {
+ errno = saveerr;
+ return 0;
+ }
+
+ /*
+ * Common point for beginning a new line -
+ *
+ * - read a line, and NUL terminate
+ * - skip lines which begin with '#'
+ * - parse off the tty names
+ * - parse off a list of user names
+ * - parse off a list of days and times
+ */
+
+again:
+
+ /*
+ * Get the next line and remove the last character, which
+ * is a '\n'. Lines which begin with '#' are all ignored.
+ */
+
+ if (fgets (buf, sizeof buf, ports) == 0) {
+ errno = saveerr;
+ return 0;
+ }
+ if (buf[0] == '#')
+ goto again;
+
+ /*
+ * Get the name of the TTY device. It is the first colon
+ * separated field, and is the name of the TTY with no
+ * leading "/dev". The entry '*' is used to specify all
+ * TTY devices.
+ */
+
+ buf[strlen (buf) - 1] = 0;
+
+ port.pt_names = ttys;
+ for (cp = buf, j = 0;j < PORT_TTY;j++) {
+ port.pt_names[j] = cp;
+ while (*cp && *cp != ':' && *cp != ',')
+ cp++;
+
+ if (! *cp)
+ goto again; /* line format error */
+
+ if (*cp == ':') /* end of tty name list */
+ break;
+
+ if (*cp == ',') /* end of current tty name */
+ *cp++ = '\0';
+ }
+ *cp++ = 0;
+ port.pt_names[j + 1] = (char *) 0;
+
+ /*
+ * Get the list of user names. It is the second colon
+ * separated field, and is a comma separated list of user
+ * names. The entry '*' is used to specify all usernames.
+ * The last entry in the list is a (char *) 0 pointer.
+ */
+
+ if (*cp != ':') {
+ port.pt_users = users;
+ port.pt_users[0] = cp;
+
+ for (j = 1;*cp != ':';cp++) {
+ if (*cp == ',' && j < PORT_IDS) {
+ *cp++ = 0;
+ port.pt_users[j++] = cp;
+ }
+ }
+ port.pt_users[j] = 0;
+ } else
+ port.pt_users = 0;
+
+ if (*cp != ':')
+ goto again;
+
+ *cp++ = 0;
+
+ /*
+ * Get the list of valid times. The times field is the third
+ * colon separated field and is a list of days of the week and
+ * times during which this port may be used by this user. The
+ * valid days are 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', and 'Sa'.
+ *
+ * In addition, the value 'Al' represents all 7 days, and 'Wk'
+ * represents the 5 weekdays.
+ *
+ * Times are given as HHMM-HHMM. The ending time may be before
+ * the starting time. Days are presumed to wrap at 0000.
+ */
+
+ if (*cp == '\0') {
+ port.pt_times = 0;
+ return &port;
+ }
+
+ port.pt_times = ptimes;
+
+ /*
+ * Get the next comma separated entry
+ */
+
+ for (j = 0;*cp && j < PORT_TIMES;j++) {
+
+ /*
+ * Start off with no days of the week
+ */
+
+ port.pt_times[j].t_days = 0;
+
+ /*
+ * Check each two letter sequence to see if it is
+ * one of the abbreviations for the days of the
+ * week or the other two values.
+ */
+
+ for (i = 0;cp[i] && cp[i + 1] && isalpha (cp[i]);i += 2) {
+ switch ((cp[i] << 8) | (cp[i + 1])) {
+ case ('S' << 8) | 'u':
+ port.pt_times[j].t_days |= 01;
+ break;
+ case ('M' << 8) | 'o':
+ port.pt_times[j].t_days |= 02;
+ break;
+ case ('T' << 8) | 'u':
+ port.pt_times[j].t_days |= 04;
+ break;
+ case ('W' << 8) | 'e':
+ port.pt_times[j].t_days |= 010;
+ break;
+ case ('T' << 8) | 'h':
+ port.pt_times[j].t_days |= 020;
+ break;
+ case ('F' << 8) | 'r':
+ port.pt_times[j].t_days |= 040;
+ break;
+ case ('S' << 8) | 'a':
+ port.pt_times[j].t_days |= 0100;
+ break;
+ case ('W' << 8) | 'k':
+ port.pt_times[j].t_days |= 076;
+ break;
+ case ('A' << 8) | 'l':
+ port.pt_times[j].t_days |= 0177;
+ break;
+ default:
+ errno = EINVAL;
+ return 0;
+ }
+ }
+
+ /*
+ * The default is 'Al' if no days were seen.
+ */
+
+ if (i == 0)
+ port.pt_times[j].t_days = 0177;
+
+ /*
+ * The start and end times are separated from each
+ * other by a '-'. The times are four digit numbers
+ * representing the times of day.
+ */
+
+ for (dtime = 0;cp[i] && isdigit (cp[i]);i++)
+ dtime = dtime * 10 + cp[i] - '0';
+
+ if (cp[i] != '-' || dtime > 2400 || dtime % 100 > 59)
+ goto again;
+ port.pt_times[j].t_start = dtime;
+ cp = cp + i + 1;
+
+ for (dtime = i = 0;cp[i] && isdigit (cp[i]);i++)
+ dtime = dtime * 10 + cp[i] - '0';
+
+ if ((cp[i] != ',' && cp[i]) ||
+ dtime > 2400 || dtime % 100 > 59)
+ goto again;
+
+ port.pt_times[j].t_end = dtime;
+ cp = cp + i + 1;
+ }
+
+ /*
+ * The end of the list is indicated by a pair of -1's for the
+ * start and end times.
+ */
+
+ port.pt_times[j].t_start = port.pt_times[j].t_end = -1;
+
+ return &port;
+}
+
+/*
+ * getttyuser - get ports information for user and tty
+ *
+ * getttyuser() searches the ports file for an entry with a TTY
+ * and user field both of which match the supplied TTY and
+ * user name. The file is searched from the beginning, so the
+ * entries are treated as an ordered list.
+ */
+
+static struct port *
+getttyuser(const char *tty, const char *user)
+{
+ int i, j;
+ struct port *port;
+
+ setportent ();
+
+ while ((port = getportent ())) {
+ if (port->pt_names == 0 || port->pt_users == 0)
+ continue;
+
+ for (i = 0;port->pt_names[i];i++)
+ if (portcmp (port->pt_names[i], tty) == 0)
+ break;
+
+ if (port->pt_names[i] == 0)
+ continue;
+
+ for (j = 0;port->pt_users[j];j++)
+ if (strcmp (user, port->pt_users[j]) == 0 ||
+ strcmp (port->pt_users[j], "*") == 0)
+ break;
+
+ if (port->pt_users[j] != 0)
+ break;
+ }
+ endportent ();
+ return port;
+}
+
+/*
+ * isttytime - tell if a given user may login at a particular time
+ *
+ * isttytime searches the ports file for an entry which matches
+ * the user name and TTY given.
+ */
+
+int
+isttytime(const char *id, const char *port, time_t when)
+{
+ int i;
+ int dtime;
+ struct port *pp;
+ struct tm *tm;
+
+ /*
+ * Try to find a matching entry for this user. Default to
+ * letting the user in - there are pleny of ways to have an
+ * entry to match all users.
+ */
+
+ if (! (pp = getttyuser (port, id)))
+ return 1;
+
+ /*
+ * The entry is there, but has no time entries - don't
+ * ever let them login.
+ */
+
+ if (pp->pt_times == 0)
+ return 0;
+
+ /*
+ * The current time is converted to HHMM format for
+ * comparision against the time values in the TTY entry.
+ */
+
+ tm = localtime (&when);
+ dtime = tm->tm_hour * 100 + tm->tm_min;
+
+ /*
+ * Each time entry is compared against the current
+ * time. For entries with the start after the end time,
+ * the comparision is made so that the time is between
+ * midnight and either the start or end time.
+ */
+
+ for (i = 0;pp->pt_times[i].t_start != -1;i++) {
+ if (! (pp->pt_times[i].t_days & PORT_DAY(tm->tm_wday)))
+ continue;
+
+ if (pp->pt_times[i].t_start <= pp->pt_times[i].t_end) {
+ if (dtime >= pp->pt_times[i].t_start &&
+ dtime <= pp->pt_times[i].t_end)
+ return 1;
+ } else {
+ if (dtime >= pp->pt_times[i].t_start ||
+ dtime <= pp->pt_times[i].t_end)
+ return 1;
+ }
+ }
+
+ /*
+ * No matching time entry was found, user shouldn't
+ * be let in right now.
+ */
+
+ return 0;
+}
diff --git a/current/lib/port.h b/current/lib/port.h
new file mode 100644
index 00000000..a02d6728
--- /dev/null
+++ b/current/lib/port.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * port.h - structure of /etc/porttime
+ *
+ * $Id: port.h,v 1.2 1997/05/01 23:14:43 marekm Exp $
+ *
+ * Each entry in /etc/porttime consists of a TTY device
+ * name or "*" to indicate all TTY devices, followed by
+ * a list of 1 or more user IDs or "*" to indicate all
+ * user names, followed by a list of zero or more valid
+ * login times. Login time entries consist of zero or
+ * more day names (Su, Mo, Tu, We, Th, Fr, Sa, Wk, Al)
+ * followed by a pair of time values in HHMM format
+ * separated by a "-".
+ */
+
+/*
+ * PORTS - Name of system port access time file.
+ * PORT_IDS - Allowable number of IDs per entry.
+ * PORT_TTY - Allowable number of TTYs per entry.
+ * PORT_TIMES - Allowable number of time entries per entry.
+ * PORT_DAY - Day of the week to a bit value (0 = Sunday).
+ */
+
+#define PORTS "/etc/porttime"
+#define PORT_IDS 64
+#define PORT_TTY 64
+#define PORT_TIMES 24
+#define PORT_DAY(day) (1<<(day))
+
+/*
+ * pt_names - pointer to array of device names in /dev/
+ * pt_users - pointer to array of applicable user IDs.
+ * pt_times - pointer to list of allowable time periods.
+ */
+
+struct port {
+ char **pt_names;
+ char **pt_users;
+ struct pt_time *pt_times;
+};
+
+/*
+ * t_days - bit array for each day of the week (0 = Sunday)
+ * t_start - starting time for this entry
+ * t_end - ending time for this entry
+ */
+
+struct pt_time {
+ short t_days;
+ short t_start;
+ short t_end;
+};
diff --git a/current/lib/prototypes.h b/current/lib/prototypes.h
new file mode 100644
index 00000000..20436dcf
--- /dev/null
+++ b/current/lib/prototypes.h
@@ -0,0 +1,228 @@
+/*
+ * prototypes.h
+ *
+ * Missing function prototypes
+ *
+ * Juha Virtanen, <jiivee@hut.fi>; November 1995
+ */
+/*
+ * $Id: prototypes.h,v 1.14 2000/08/26 18:27:17 marekm Exp $
+ *
+ * Added a macro to work around ancient (non-ANSI) compilers, just in case
+ * someone ever tries to compile this with SunOS cc... --marekm
+ */
+
+#ifndef _PROTOTYPES_H
+#define _PROTOTYPES_H
+
+#include <sys/stat.h>
+#include <utmp.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "defines.h"
+
+/* addgrps.c */
+extern int add_groups(const char *);
+extern void add_cons_grps(void);
+
+/* age.c */
+#ifdef SHADOWPWD
+extern void agecheck(const struct passwd *, const struct spwd *);
+extern int expire(const struct passwd *, const struct spwd *);
+extern int isexpired(const struct passwd *, const struct spwd *);
+#else
+extern void agecheck(const struct passwd *);
+extern int expire(const struct passwd *);
+extern int isexpired(const struct passwd *);
+#endif
+
+/* basename() renamed to Basename() to avoid libc name space confusion */
+/* basename.c */
+extern char *Basename(char *str);
+
+/* chkshell.c */
+extern int check_shell(const char *);
+
+/* chowndir.c */
+extern int chown_tree(const char *, uid_t, uid_t, gid_t, gid_t);
+
+/* chowntty.c */
+extern void chown_tty(const char *, const struct passwd *);
+
+/* console.c */
+extern int console(const char *);
+extern int is_listed(const char *, const char *, int);
+
+/* copydir.c */
+extern int copy_tree(const char *, const char *, uid_t, gid_t);
+extern int remove_tree(const char *);
+
+/* encrypt.c */
+extern char *pw_encrypt(const char *, const char *);
+
+/* entry.c */
+extern void pw_entry(const char *, struct passwd *);
+
+/* env.c */
+extern void addenv(const char *, const char *);
+extern void initenv(void);
+extern void set_env(int, char * const *);
+extern void sanitize_env(void);
+
+/* fields.c */
+extern void change_field(char *, size_t, const char *);
+extern int valid_field(const char *, const char *);
+
+/* fputsx.c */
+extern char *fgetsx(char *, int, FILE *);
+extern int fputsx(const char *, FILE *);
+
+/* grdbm.c */
+extern int gr_dbm_remove(const struct group *);
+extern int gr_dbm_update(const struct group *);
+extern int gr_dbm_present(void);
+
+/* grent.c */
+extern int putgrent(const struct group *, FILE *);
+
+/* grpack.c */
+extern int gr_pack(const struct group *, char *);
+extern int gr_unpack(char *, int, struct group *);
+
+#ifdef SHADOWGRP
+/* gsdbm.c */
+extern int sg_dbm_remove(const char *);
+extern int sg_dbm_update(const struct sgrp *);
+extern int sg_dbm_present(void);
+
+/* gspack.c */
+extern int sgr_pack(const struct sgrp *, char *);
+extern int sgr_unpack(char *, int, struct sgrp *);
+#endif
+
+/* hushed.c */
+extern int hushed(const struct passwd *);
+
+/* limits.c */
+extern void setup_limits(const struct passwd *);
+
+/* list.c */
+extern char **add_list(char **, const char *);
+extern char **del_list(char **, const char *);
+extern char **dup_list(char * const *);
+extern int is_on_list(char * const *, const char *);
+extern char **comma_to_list(const char *);
+
+/* login.c */
+extern void login_prompt(const char *, char *, int);
+
+/* login_desrpc.c */
+extern int login_desrpc(const char *);
+
+/* mail.c */
+extern void mailcheck(void);
+
+/* motd.c */
+extern void motd(void);
+
+/* myname.c */
+extern struct passwd *get_my_pwent(void);
+
+/* obscure.c */
+extern int obscure(const char *, const char *, const struct passwd *);
+
+/* pam_pass.c */
+extern int do_pam_passwd(const char *, int, int);
+
+/* port.c */
+extern int isttytime(const char *, const char *, time_t);
+
+/* pwd2spwd.c */
+#ifdef SHADOWPWD
+extern struct spwd *pwd_to_spwd(const struct passwd *);
+#endif
+
+/* pwdcheck.c */
+extern void passwd_check(const char *, const char *, const char *);
+
+/* pwd_init.c */
+extern void pwd_init(void);
+
+/* pwdbm.c */
+extern int pw_dbm_remove(const struct passwd *);
+extern int pw_dbm_update(const struct passwd *);
+extern int pw_dbm_present(void);
+
+/* pwpack.c */
+extern int pw_pack(const struct passwd *, char *);
+extern int pw_unpack(char *, int, struct passwd *);
+
+/* rad64.c */
+extern int c64i(int);
+extern int i64c(int);
+
+/* rlogin.c */
+extern int do_rlogin(const char *, char *, int, char *, int);
+
+/* salt.c */
+extern char *crypt_make_salt(void);
+
+/* setugid.c */
+extern int setup_groups(const struct passwd *);
+extern int change_uid(const struct passwd *);
+extern int setup_uid_gid(const struct passwd *, int);
+
+/* setup.c */
+extern void setup(struct passwd *);
+
+/* setupenv.c */
+extern void setup_env(struct passwd *);
+
+/* shell.c */
+extern void shell(const char *, const char *);
+
+#ifdef SHADOWPWD
+/* spdbm.c */
+extern int sp_dbm_remove(const char *);
+extern int sp_dbm_update(const struct spwd *);
+extern int sp_dbm_present(void);
+
+/* sppack.c */
+extern int spw_pack(const struct spwd *, char *);
+extern int spw_unpack(char *, int, struct spwd *);
+#endif
+
+/* strtoday.c */
+extern long strtoday(const char *);
+
+/* suauth.c */
+extern int check_su_auth(const char *, const char *);
+
+/* sulog.c */
+extern void sulog(const char *, int, const char *, const char *);
+
+/* sub.c */
+extern void subsystem(const struct passwd *);
+
+/* ttytype.c */
+extern void ttytype(const char *);
+
+/* tz.c */
+extern char *tz(const char *);
+
+/* ulimit.c */
+extern void set_filesize_limit(int);
+
+/* utmp.c */
+extern void checkutmp(int);
+extern void setutmp(const char *, const char *, const char *);
+
+/* valid.c */
+extern int valid(const char *, const struct passwd *);
+
+/* xmalloc.c */
+extern char *xmalloc(size_t);
+extern char *xstrdup(const char *);
+
+#endif /* _PROTOTYPES_H */
diff --git a/current/lib/putgrent.c b/current/lib/putgrent.c
new file mode 100644
index 00000000..6559cd92
--- /dev/null
+++ b/current/lib/putgrent.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <grp.h>
+#include "prototypes.h"
+#include "defines.h"
+
+int
+putgrent(const struct group *g, FILE *f)
+{
+ char *buf, *cp;
+ int i;
+ size_t size;
+
+ if (!g || !f)
+ return -1;
+
+ /* calculate the required buffer size (40 is added for the
+ numeric GID, colons, newline, and terminating NUL). */
+ size = strlen(g->gr_name) + strlen(g->gr_passwd) + 40;
+ for (i = 0; g->gr_mem && g->gr_mem[i]; i++)
+ size += strlen(g->gr_mem[i]) + 1;
+
+ buf = malloc(size);
+ if (!buf)
+ return -1;
+
+ sprintf(buf, "%s:%s:%ld:", g->gr_name, g->gr_passwd, (long) g->gr_gid);
+ cp = buf + strlen(buf);
+ for (i = 0; g->gr_mem && g->gr_mem[i]; i++) {
+ if (i > 0)
+ *cp++ = ',';
+ strcpy(cp, g->gr_mem[i]);
+ cp += strlen(cp);
+ }
+ *cp++ = '\n';
+ *cp = '\0';
+
+ if (fputsx(buf, f) == EOF || ferror(f)) {
+ free(buf);
+ return -1;
+ }
+
+ free(buf);
+ return 0;
+}
diff --git a/current/lib/putpwent.c b/current/lib/putpwent.c
new file mode 100644
index 00000000..bdc011c3
--- /dev/null
+++ b/current/lib/putpwent.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: putpwent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
+
+#include "defines.h"
+#include <stdio.h>
+#include <pwd.h>
+
+/*
+ * putpwent - Output a (struct passwd) in character format
+ *
+ * putpwent() writes out a (struct passwd) in the format it appears
+ * in in flat ASCII files.
+ *
+ * (Author: Dr. Micheal Newberry)
+ */
+
+int
+putpwent(const struct passwd *p, FILE *f)
+{
+ int status;
+
+#if defined(SUN) || defined(BSD) || defined(SUN4)
+ status = fprintf (f, "%s:%s:%d:%d:%s,%s:%s:%s\n",
+ p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid,
+ p->pw_gecos, p->pw_comment, p->pw_dir, p->pw_shell) == EOF;
+#else
+ status = fprintf (f, "%s:%s", p->pw_name, p->pw_passwd) == EOF;
+#ifdef ATT_AGE
+ if (p->pw_age && p->pw_age[0])
+ status |= fprintf (f, ",%s", p->pw_age) == EOF;
+#endif
+ status |= fprintf (f, ":%d:%d:%s", p->pw_uid, p->pw_gid,
+ p->pw_gecos) == EOF;
+#ifdef ATT_COMMENT
+ if (p->pw_comment && p->pw_comment[0])
+ status |= fprintf (f, ",%s", p->pw_comment) == EOF;
+#endif
+ status |= fprintf (f, ":%s:%s\n", p->pw_dir, p->pw_shell) == EOF;
+#endif
+ return status;
+}
diff --git a/current/lib/putspent.c b/current/lib/putspent.c
new file mode 100644
index 00000000..941d76bc
--- /dev/null
+++ b/current/lib/putspent.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef SHADOWPWD /*{*/
+#ifndef HAVE_PUTSPENT
+
+#include "rcsid.h"
+RCSID("$Id: putspent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
+
+#include <sys/types.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <stdio.h>
+
+int
+putspent(const struct spwd *sp, FILE *fp)
+{
+ int errors = 0;
+
+ if (! fp || ! sp)
+ return -1;
+
+ if (fprintf (fp, "%s:%s:", sp->sp_namp, sp->sp_pwdp) < 0)
+ errors++;
+
+ if (sp->sp_lstchg != -1) {
+ if (fprintf (fp, "%ld:", sp->sp_lstchg) < 0)
+ errors++;
+ } else if (putc (':', fp) == EOF)
+ errors++;
+
+ if (sp->sp_min != -1) {
+ if (fprintf (fp, "%ld:", sp->sp_min) < 0)
+ errors++;
+ } else if (putc (':', fp) == EOF)
+ errors++;
+
+ if (sp->sp_max != -1) {
+ if (fprintf (fp, "%ld:", sp->sp_max) < 0)
+ errors++;
+ } else if (putc (':', fp) == EOF)
+ errors++;
+
+ if (sp->sp_warn != -1) {
+ if (fprintf (fp, "%ld:", sp->sp_warn) < 0)
+ errors++;
+ } else if (putc (':', fp) == EOF)
+ errors++;
+
+ if (sp->sp_inact != -1) {
+ if (fprintf (fp, "%ld:", sp->sp_inact) < 0)
+ errors++;
+ } else if (putc (':', fp) == EOF)
+ errors++;
+
+ if (sp->sp_expire != -1) {
+ if (fprintf (fp, "%ld:", sp->sp_expire) < 0)
+ errors++;
+ } else if (putc (':', fp) == EOF)
+ errors++;
+
+ if (sp->sp_flag != -1) {
+ if (fprintf (fp, "%ld", sp->sp_flag) < 0)
+ errors++;
+ }
+ if (putc ('\n', fp) == EOF)
+ errors++;
+
+ if (errors)
+ return -1;
+ else
+ return 0;
+}
+#endif
+#endif /*}*/
diff --git a/current/lib/pwauth.c b/current/lib/pwauth.c
new file mode 100644
index 00000000..bce32f22
--- /dev/null
+++ b/current/lib/pwauth.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright 1992 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: pwauth.c,v 1.11 2000/08/26 18:27:17 marekm Exp $")
+
+#include <sys/types.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "pwauth.h"
+#include "getdef.h"
+
+#ifdef SKEY
+#include <skey.h>
+#endif
+
+#ifdef OPIE
+#include <opie.h>
+#endif
+
+#ifdef __linux__ /* standard password prompt by default */
+static const char *PROMPT = gettext_noop("Password: ");
+#else
+static const char *PROMPT = gettext_noop("%s's Password: ");
+#endif
+
+extern char *getpass();
+extern char *getpass_with_echo();
+
+#ifdef AUTH_METHODS
+/*
+ * Look-up table for bound-in methods. Put the name that the
+ * method is known by in the password field as "name" and a
+ * pointer to the function
+ */
+
+struct method {
+ char *name;
+ int (*func)(const char *, int, const char *);
+};
+
+#ifdef PAD_AUTH
+int pad_auth();
+#endif
+static struct method methods[] = {
+#ifdef PAD_AUTH
+ { "pad", pad_auth },
+#endif
+ { "", 0 }
+};
+#endif /* AUTH_METHODS */
+
+int wipe_clear_pass = 1;
+char *clear_pass = NULL;
+
+/*
+ * _old_auth - perform getpass/crypt authentication
+ *
+ * _old_auth gets the user's cleartext password and encrypts it
+ * using the salt in the encrypted password. The results are
+ * compared.
+ */
+
+static int
+_old_auth(const char *cipher, const char *user, int reason, const char *input)
+{
+ char prompt[1024];
+ char *clear = NULL;
+ const char *cp;
+ int retval;
+#ifdef SKEY
+ int use_skey = 0;
+ char challenge_info[40];
+ struct skey skey;
+#endif
+
+#ifdef OPIE
+ int use_opie = 0;
+ char o_challenge_info[OPIE_CHALLENGE_MAX + 1];
+ struct opie opie;
+ /*
+ * This implementation is based almost entirely on the SKEY code
+ * above. Thus the opie struct is called skey, etc. I am unaware
+ * if the system works at the same time, but I cannot imagine why
+ * anyone would want to do this....
+ * -- A.R.
+ * Mod: 5/14/98 A.R.
+ * Made the OPIE code separate from the S/Key code. Now
+ * (conceivably) both can be compiled in and function apart from
+ * one another (assuming a sysadmin really wants to maintain OPIE
+ * and an S/Key databases....).
+ *
+ * Also cleaned up the code a bit. Will be adding second-prompt
+ * support (the traditional Echo-on S/Key/OPIE-only prompts to let
+ * the users see the one-time passwords they are typing/pasting
+ * in....
+ * -- A.R.
+ */
+#endif
+
+ /*
+ * There are programs for adding and deleting authentication data.
+ */
+
+ if (reason == PW_ADD || reason == PW_DELETE)
+ return 0;
+
+ /*
+ * There are even programs for changing the user name ...
+ */
+
+ if (reason == PW_CHANGE && input != (char *) 0)
+ return 0;
+
+ /*
+ * WARNING:
+ *
+ * When we change a password and we are root, we don't prompt.
+ * This is so root can change any password without having to
+ * know it. This is a policy decision that might have to be
+ * revisited.
+ */
+
+ if (reason == PW_CHANGE && getuid () == 0)
+ return 0;
+
+ /*
+ * WARNING:
+ *
+ * When we are logging in a user with no ciphertext password,
+ * we don't prompt for the password or anything. In reality
+ * the user could just hit <ENTER>, so it doesn't really
+ * matter.
+ */
+
+ if (cipher == (char *) 0 || *cipher == '\0')
+ return 0;
+
+#ifdef SKEY
+ /*
+ * If the user has an S/KEY entry show them the pertinent info
+ * and then we can try validating the created cyphertext and the SKEY.
+ * If there is no SKEY information we default to not using SKEY.
+ */
+
+ if (skeychallenge (&skey, user, challenge_info) == 0)
+ use_skey = 1;
+#endif
+
+#ifdef OPIE
+ /*
+ * Ditto above, for OPIE passwords.
+ * -- AR
+ */
+
+ o_challenge_info[0] = '\0';
+ if (opiechallenge(&opie, user, o_challenge_info) == 0)
+ use_opie = 1;
+
+ if (use_opie == 0)
+ opieverify(&opie, (char *)NULL);
+ /*
+ * This call to opieverify is necessary within OPIE's interface:
+ * Every call to opiechallenge(), which checks to see if the user
+ * has an OPIE password, and if so get the challenge, must be
+ * accompanied by exactly one call to opieverify, which clears
+ * any outstanding locks, and otherwise cleans up.
+ * -- AR
+ */
+#endif
+
+ /*
+ * Prompt for the password as required. FTPD and REXECD both
+ * get the cleartext password for us.
+ */
+
+ if (reason != PW_FTP && reason != PW_REXEC && !input) {
+ if (! (cp = getdef_str ("LOGIN_STRING")))
+ cp = _(PROMPT);
+#ifdef SKEY
+ if (use_skey)
+ printf ("[%s]\n", challenge_info);
+#endif
+
+#ifdef OPIE
+ if (use_opie)
+ printf("[ %s ]\n", o_challenge_info);
+#endif
+
+ snprintf(prompt, sizeof prompt, cp, user);
+ clear = getpass(prompt);
+ if (!clear) {
+ static char c[1];
+ c[0] = '\0';
+ clear = c;
+ }
+ input = clear;
+ }
+
+ /*
+ * Convert the cleartext password into a ciphertext string.
+ * If the two match, the return value will be zero, which is
+ * SUCCESS. Otherwise we see if SKEY is being used and check
+ * the results there as well.
+ */
+
+ retval = strcmp(pw_encrypt(input, cipher), cipher);
+
+#ifdef OPIE
+ /*
+ * This is required because using OPIE, opieverify() MUST be called
+ * opiechallenge() above even if OPIE isn't being used in this case,
+ * so locks get released, etc.
+ * -- AR
+ */
+
+ if ((retval == 0) && use_opie)
+ opieverify(&opie, (char *)NULL);
+#endif
+
+#if (defined(SKEY) || defined(OPIE))
+ /*
+ * If (1) The password fails to match, and
+ * (2) The password is empty and
+ * (3) We are using OPIE or S/Key, then
+ * ...Re-prompt, with echo on.
+ * -- AR 8/22/1999
+ */
+ if (retval && !input[0] &&
+ (0
+#ifdef SKEY
+ || use_skey
+#endif
+#ifdef OPIE
+ || use_opie
+#endif
+ )) {
+ strncat(prompt, _("(Echo on) "),
+ (sizeof(prompt) - strlen(prompt)));
+ clear = getpass_with_echo(prompt);
+ if (!clear) {
+ static char c[1];
+ c[0] = '\0';
+ clear = c;
+ }
+ input = clear;
+ }
+#endif
+
+#ifdef SKEY
+ if (retval && use_skey) {
+ int passcheck = -1;
+
+#if 0 /* some skey libs don't have skey_passcheck. --marekm */
+ passcheck = skey_passcheck(user, input);
+#else
+ if (skeyverify(&skey, input) == 0)
+ passcheck = skey.n;
+#endif /* if 0 */
+ if (passcheck > 0)
+ retval = 0;
+ }
+#endif
+
+#ifdef OPIE
+ if (retval && use_opie) {
+ if (opieverify(&opie, input) == 0)
+ retval = 0;
+ }
+#endif /* OPIE */
+
+ /*
+ * Things like RADIUS authentication may need the password -
+ * if the external variable wipe_clear_pass is zero, we will
+ * not wipe it (the caller should wipe clear_pass when it is
+ * no longer needed). --marekm
+ */
+
+ clear_pass = clear;
+ if (wipe_clear_pass && clear && *clear)
+ strzero(clear);
+ return retval;
+}
+
+#ifdef AUTH_METHODS
+/*
+ * _pw_auth - perform alternate password authentication
+ *
+ * pw_auth executes the alternate password authentication method
+ * described in the user's password entry. _pw_auth does the real
+ * work, pw_auth splits the authentication string into individual
+ * command names.
+ */
+
+static int
+_pw_auth(const char *command, const char *user, int reason, const char *input)
+{
+ RETSIGTYPE (*sigint)();
+ RETSIGTYPE (*sigquit)();
+#ifdef SIGTSTP
+ RETSIGTYPE (*sigtstp)();
+#endif
+ int pid;
+ int status;
+ int i;
+ char * const argv[5];
+ int argc = 0;
+ int pipes[2];
+ char *empty_env = NULL;
+ int use_pipe;
+
+ /*
+ * Start with a quick sanity check. ALL command names must
+ * be fully-qualified path names.
+ */
+
+ if (command[0] != '/')
+ return -1;
+
+ /*
+ * Set the keyboard signals to be ignored. When the user kills
+ * the child we don't want the parent dying as well.
+ */
+
+ sigint = signal (SIGINT, SIG_IGN);
+ sigquit = signal (SIGQUIT, SIG_IGN);
+#ifdef SIGTSTP
+ sigtstp = signal (SIGTSTP, SIG_IGN);
+#endif
+
+ /*
+ * FTP and REXEC reasons don't give the program direct access
+ * to the user. This means that the program can only get input
+ * from this function. So we set up a pipe for that purpose.
+ */
+
+ use_pipe = (reason == PW_FTP || reason == PW_REXEC);
+ if (use_pipe)
+ if (pipe (pipes))
+ return -1;
+
+ /*
+ * The program will be forked off with the parent process waiting
+ * on the child to tell it how successful it was.
+ */
+
+ switch (pid = fork ()) {
+
+ /*
+ * The fork() failed completely. Clean up as needed and
+ * return to the caller.
+ */
+ case -1:
+ if (use_pipe) {
+ close (pipes[0]);
+ close (pipes[1]);
+ }
+ return -1;
+ case 0:
+
+ /*
+ * Let the child catch the SIGINT and SIGQUIT
+ * signals. The parent, however, will continue
+ * to ignore them.
+ */
+ signal (SIGINT, SIG_DFL);
+ signal (SIGQUIT, SIG_DFL);
+
+ /*
+ * Set up the command line. The first argument is
+ * the name of the command being executed. The
+ * second is the command line option for the reason,
+ * and the third is the user name.
+ */
+ argv[argc++] = command;
+ switch (reason) {
+ case PW_SU: argv[argc++] = "-s"; break;
+ case PW_LOGIN: argv[argc++] = "-l"; break;
+ case PW_ADD: argv[argc++] = "-a"; break;
+ case PW_CHANGE: argv[argc++] = "-c"; break;
+ case PW_DELETE: argv[argc++] = "-d"; break;
+ case PW_TELNET: argv[argc++] = "-t"; break;
+ case PW_RLOGIN: argv[argc++] = "-r"; break;
+ case PW_FTP: argv[argc++] = "-f"; break;
+ case PW_REXEC: argv[argc++] = "-x"; break;
+ }
+ if (reason == PW_CHANGE && input)
+ argv[argc++] = input;
+
+ argv[argc++] = user;
+ argv[argc] = (char *) 0;
+
+ /*
+ * The FTP and REXEC reasons use a pipe to communicate
+ * with the parent. The other standard I/O descriptors
+ * are closed and re-opened as /dev/null.
+ */
+ if (use_pipe) {
+ close (0);
+ close (1);
+ close (2);
+
+ if (dup (pipes[0]) != 0)
+ exit (1);
+
+ close (pipes[0]);
+ close (pipes[1]);
+
+ if (open ("/dev/null", O_WRONLY) != 1)
+ exit (1);
+
+ if (open ("/dev/null", O_WRONLY) != 2)
+ exit (1);
+ }
+
+ /*
+ * Now we execute the command directly.
+ * Do it with empty environment for safety. --marekm
+ */
+ execve(command, argv, &empty_env);
+ _exit((errno == ENOENT) ? 127 : 126);
+ /*NOTREACHED*/
+ default:
+ /*
+ * FTP and REXEC cause a single line of text to be
+ * sent to the child over a pipe that was set up
+ * earlier.
+ */
+ if (use_pipe) {
+ close (pipes[0]);
+
+ if (input)
+ write (pipes[1], input, strlen (input));
+
+ write (pipes[1], "\n", 1);
+ close (pipes[1]);
+ }
+
+ /*
+ * Wait on the child to die. When it does you will
+ * get the exit status and use that to determine if
+ * the authentication program was successful.
+ */
+ while ((i = wait (&status)) != pid && i != -1)
+ ;
+
+ /*
+ * Re-set the signals to their earlier values.
+ */
+ signal (SIGINT, sigint);
+ signal (SIGQUIT, sigquit);
+#ifdef SIGTSTP
+ signal (SIGTSTP, sigtstp);
+#endif
+
+ /*
+ * Make sure we found the right process!
+ */
+ if (i == -1)
+ return -1;
+
+ if (status == 0)
+ return 0;
+ else
+ return -1;
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * _builtin_auth - lookup routine in table and execute
+ */
+
+static int
+_builtin_auth(const char *command, const char *user, int reason, const char *input)
+{
+ int i;
+
+ /*
+ * Scan the table, looking for a match. If we fall off
+ * the end, it must mean that this method isn't supported,
+ * so we fail the authentication.
+ */
+
+ for (i = 0;methods[i].name[0];i++) {
+ if (! strcmp (command, methods[i].name))
+ break;
+ }
+ if (methods[i].name[0] == '\0')
+ return -1;
+
+ /*
+ * Call the pointed to function with the other three
+ * arguments.
+ */
+
+ return (methods[i].func) (user, reason, input);
+}
+#endif /* AUTH_METHODS */
+
+/*
+ * This function does the real work. It splits the list of program names
+ * up into individual programs and executes them one at a time.
+ */
+
+int
+pw_auth(const char *command, const char *user, int reason, const char *input)
+{
+#ifdef AUTH_METHODS
+ char buf[256];
+ char *cmd, *end;
+ int rc;
+
+ /*
+ * Quick little sanity check ...
+ */
+
+ if (strlen (command) >= sizeof buf)
+ return -1;
+
+ strcpy(buf, command); /* safe (because of the above check) --marekm */
+
+ /*
+ * Find each command and make sure it is NUL-terminated. Then
+ * invoke _pw_auth to actually run the program. The first
+ * failing program ends the whole mess.
+ */
+
+ for (cmd = buf;cmd;cmd = end) {
+ if ((end = strchr (cmd, ';')))
+ *end++ = '\0';
+
+ if (cmd[0] != '@')
+ rc = _old_auth (cmd, user, reason, input);
+ else if (cmd[1] == '/')
+ rc = _pw_auth (cmd + 1, user, reason, input);
+ else
+ rc = _builtin_auth (cmd + 1, user, reason, input);
+ if (rc)
+ return -1;
+ }
+ return 0;
+#else
+ return _old_auth(command, user, reason, input);
+#endif
+}
diff --git a/current/lib/pwauth.h b/current/lib/pwauth.h
new file mode 100644
index 00000000..ab6017b4
--- /dev/null
+++ b/current/lib/pwauth.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1992 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: pwauth.h,v 1.2 1997/05/01 23:14:44 marekm Exp $
+ */
+
+#if __STDC__
+int pw_auth(const char *program,const char *user,int flag,const char *input);
+#else
+int pw_auth ();
+#endif
+
+/*
+ * Local access
+ */
+
+#define PW_SU 1
+#define PW_LOGIN 2
+
+/*
+ * Administrative functions
+ */
+
+#define PW_ADD 101
+#define PW_CHANGE 102
+#define PW_DELETE 103
+
+/*
+ * Network access
+ */
+
+#define PW_TELNET 201
+#define PW_RLOGIN 202
+#define PW_FTP 203
+#define PW_REXEC 204
diff --git a/current/lib/pwdbm.c b/current/lib/pwdbm.c
new file mode 100644
index 00000000..c0de8460
--- /dev/null
+++ b/current/lib/pwdbm.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef NDBM /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: pwdbm.c,v 1.4 1997/12/14 20:07:19 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <pwd.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <ndbm.h>
+extern DBM *pw_dbm;
+
+/*
+ * pw_dbm_update
+ *
+ * Updates the DBM password files, if they exist.
+ */
+
+int
+pw_dbm_update(const struct passwd *pw)
+{
+ datum key;
+ datum content;
+ char data[BUFSIZ];
+ int len;
+ static int once;
+
+ if (! once) {
+ if (! pw_dbm)
+ setpwent ();
+ once++;
+ }
+ if (! pw_dbm)
+ return 0;
+
+ len = pw_pack (pw, data);
+ content.dsize = len;
+ content.dptr = data;
+
+ key.dsize = strlen (pw->pw_name);
+ key.dptr = pw->pw_name;
+
+ if (dbm_store(pw_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ /*
+ * XXX - on systems with 16-bit UIDs (such as Linux/x86)
+ * name "aa" and UID 24929 will give the same key. This
+ * happens only rarely, but code which only "works most
+ * of the time" is not good enough...
+ *
+ * This needs to be fixed in several places (pwdbm.c,
+ * grdbm.c, pwent.c, grent.c). Fixing it will cause
+ * incompatibility with existing dbm files.
+ *
+ * Summary: don't use this stuff for now. --marekm
+ */
+
+ key.dsize = sizeof pw->pw_uid;
+ key.dptr = (char *) &pw->pw_uid;
+
+ if (dbm_store(pw_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * pw_dbm_remove
+ *
+ * Removes the DBM password entry, if it exists.
+ */
+
+int
+pw_dbm_remove(const struct passwd *pw)
+{
+ datum key;
+ static int once;
+ char data[BUFSIZ];
+
+ if (! once) {
+ if (! pw_dbm)
+ setpwent ();
+ once++;
+ }
+ if (! pw_dbm)
+ return 0;
+
+ key.dsize = strlen (pw->pw_name);
+ key.dptr = pw->pw_name;
+
+ if (dbm_delete (pw_dbm, key))
+ return 0;
+
+ key.dsize = sizeof pw->pw_uid;
+ key.dptr = (char *) &pw->pw_uid;
+
+ if (dbm_delete (pw_dbm, key))
+ return 0;
+
+ return 1;
+}
+
+
+int
+pw_dbm_present(void)
+{
+ return (access(PASSWD_PAG_FILE, F_OK) == 0);
+}
+#endif /* NDBM */
diff --git a/current/lib/pwio.c b/current/lib/pwio.c
new file mode 100644
index 00000000..70b3d9ab
--- /dev/null
+++ b/current/lib/pwio.c
@@ -0,0 +1,186 @@
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: pwio.c,v 1.11 2000/09/02 18:40:43 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include <stdio.h>
+
+#include "commonio.h"
+#include "pwio.h"
+
+extern struct passwd *sgetpwent(const char *);
+extern int putpwent(const struct passwd *, FILE *);
+
+struct passwd *
+__pw_dup(const struct passwd *pwent)
+{
+ struct passwd *pw;
+
+ if (!(pw = (struct passwd *) malloc(sizeof *pw)))
+ return NULL;
+ *pw = *pwent;
+ if (!(pw->pw_name = strdup(pwent->pw_name)))
+ return NULL;
+ if (!(pw->pw_passwd = strdup(pwent->pw_passwd)))
+ return NULL;
+#ifdef ATT_AGE
+ if (!(pw->pw_age = strdup(pwent->pw_age)))
+ return NULL;
+#endif
+#ifdef ATT_COMMENT
+ if (!(pw->pw_comment = strdup(pwent->pw_comment)))
+ return NULL;
+#endif
+ if (!(pw->pw_gecos = strdup(pwent->pw_gecos)))
+ return NULL;
+ if (!(pw->pw_dir = strdup(pwent->pw_dir)))
+ return NULL;
+ if (!(pw->pw_shell = strdup(pwent->pw_shell)))
+ return NULL;
+ return pw;
+}
+
+static void *
+passwd_dup(const void *ent)
+{
+ const struct passwd *pw = ent;
+ return __pw_dup(pw);
+}
+
+static void
+passwd_free(void *ent)
+{
+ struct passwd *pw = ent;
+
+ free(pw->pw_name);
+ free(pw->pw_passwd);
+#ifdef ATT_AGE
+ free(pw->pw_age);
+#endif
+#ifdef ATT_COMMENT
+ free(pw->pw_comment);
+#endif
+ free(pw->pw_gecos);
+ free(pw->pw_dir);
+ free(pw->pw_shell);
+ free(pw);
+}
+
+static const char *
+passwd_getname(const void *ent)
+{
+ const struct passwd *pw = ent;
+ return pw->pw_name;
+}
+
+static void *
+passwd_parse(const char *line)
+{
+ return (void *) sgetpwent(line);
+}
+
+static int
+passwd_put(const void *ent, FILE *file)
+{
+ const struct passwd *pw = ent;
+ return (putpwent(pw, file) == -1) ? -1 : 0;
+}
+
+static struct commonio_ops passwd_ops = {
+ passwd_dup,
+ passwd_free,
+ passwd_getname,
+ passwd_parse,
+ passwd_put,
+ fgets,
+ fputs
+};
+
+static struct commonio_db passwd_db = {
+ PASSWD_FILE, /* filename */
+ &passwd_ops, /* ops */
+ NULL, /* fp */
+ NULL, /* head */
+ NULL, /* tail */
+ NULL, /* cursor */
+ 0, /* changed */
+ 0, /* isopen */
+ 0, /* locked */
+ 0 /* readonly */
+};
+
+int
+pw_name(const char *filename)
+{
+ return commonio_setname(&passwd_db, filename);
+}
+
+int
+pw_lock(void)
+{
+ return commonio_lock(&passwd_db);
+}
+
+int
+pw_open(int mode)
+{
+ return commonio_open(&passwd_db, mode);
+}
+
+const struct passwd *
+pw_locate(const char *name)
+{
+ return commonio_locate(&passwd_db, name);
+}
+
+int
+pw_update(const struct passwd *pw)
+{
+ return commonio_update(&passwd_db, (const void *) pw);
+}
+
+int
+pw_remove(const char *name)
+{
+ return commonio_remove(&passwd_db, name);
+}
+
+int
+pw_rewind(void)
+{
+ return commonio_rewind(&passwd_db);
+}
+
+const struct passwd *
+pw_next(void)
+{
+ return commonio_next(&passwd_db);
+}
+
+int
+pw_close(void)
+{
+ return commonio_close(&passwd_db);
+}
+
+int
+pw_unlock(void)
+{
+ return commonio_unlock(&passwd_db);
+}
+
+struct commonio_entry *
+__pw_get_head(void)
+{
+ return passwd_db.head;
+}
+
+void
+__pw_del_entry(const struct commonio_entry *ent)
+{
+ commonio_del_entry(&passwd_db, ent);
+}
diff --git a/current/lib/pwio.h b/current/lib/pwio.h
new file mode 100644
index 00000000..199f67da
--- /dev/null
+++ b/current/lib/pwio.h
@@ -0,0 +1,12 @@
+extern struct passwd *__pw_dup(const struct passwd *);
+extern void __pw_set_changed(void);
+extern int pw_close(void);
+extern const struct passwd *pw_locate(const char *);
+extern int pw_lock(void);
+extern int pw_name(const char *);
+extern const struct passwd *pw_next(void);
+extern int pw_open(int);
+extern int pw_remove(const char *);
+extern int pw_rewind(void);
+extern int pw_unlock(void);
+extern int pw_update(const struct passwd *);
diff --git a/current/lib/pwpack.c b/current/lib/pwpack.c
new file mode 100644
index 00000000..67053baf
--- /dev/null
+++ b/current/lib/pwpack.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: pwpack.c,v 1.4 1998/04/16 19:57:42 marekm Exp $")
+
+#include <sys/types.h>
+#include "defines.h"
+#include <stdio.h>
+#include <pwd.h>
+
+
+/*
+ * pw_pack - convert a (struct pwd) to a packed record
+ * WARNING: buf must be large enough, no check for overrun!
+ */
+
+int
+pw_pack(const struct passwd *passwd, char *buf)
+{
+ char *cp;
+
+ cp = buf;
+ strcpy (cp, passwd->pw_name);
+ cp += strlen (cp) + 1;
+
+ strcpy (cp, passwd->pw_passwd);
+#ifdef ATT_AGE
+ if (passwd->pw_age[0]) {
+ *cp++ = ',';
+ strcat (cp, passwd->pw_age);
+ }
+#endif
+ cp += strlen (cp) + 1;
+
+ memcpy (cp, (const char *) &passwd->pw_uid, sizeof passwd->pw_uid);
+ cp += sizeof passwd->pw_uid;
+
+ memcpy (cp, (const char *) &passwd->pw_gid, sizeof passwd->pw_gid);
+ cp += sizeof passwd->pw_gid;
+#ifdef BSD_QUOTA
+ memcpy (cp, (const char *) &passwd->pw_quota, sizeof passwd->pw_quota);
+ cp += sizeof passwd->pw_quota;
+#endif
+#ifdef ATT_COMMENT
+ if (passwd->pw_comment) {
+ strcpy (cp, passwd->pw_comment);
+ cp += strlen (cp) + 1;
+ } else
+ *cp++ = '\0';
+#endif
+ strcpy (cp, passwd->pw_gecos);
+ cp += strlen (cp) + 1;
+
+ strcpy (cp, passwd->pw_dir);
+ cp += strlen (cp) + 1;
+
+ strcpy (cp, passwd->pw_shell);
+ cp += strlen (cp) + 1;
+
+ return cp - buf;
+}
+
+/*
+ * pw_unpack - convert a packed (struct pwd) record to a (struct pwd)
+ */
+
+int
+pw_unpack(char *buf, int len, struct passwd *passwd)
+{
+ char *org = buf;
+#ifdef ATT_AGE
+ char *cp;
+#endif
+
+ memzero(passwd, sizeof *passwd);
+
+ passwd->pw_name = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ passwd->pw_passwd = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+#ifdef ATT_AGE
+ if (cp = strchr (passwd->pw_passwd, ',')) {
+ *cp++ = '\0';
+ passwd->pw_age = cp;
+ } else
+ passwd->pw_age = "";
+#endif
+
+ memcpy ((void *) &passwd->pw_uid, (void *) buf, sizeof passwd->pw_uid);
+ buf += sizeof passwd->pw_uid;
+ if (buf - org > len)
+ return -1;
+
+ memcpy ((void *) &passwd->pw_gid, (void *) buf, sizeof passwd->pw_gid);
+ buf += sizeof passwd->pw_gid;
+ if (buf - org > len)
+ return -1;
+
+#ifdef BSD_QUOTA
+ memcpy ((void *) &passwd->pw_quota, (void *) buf,
+ sizeof passwd->pw_quota);
+ buf += sizeof passwd->pw_quota;
+ if (buf - org > len)
+ return -1;
+#endif
+#ifdef ATT_COMMENT
+ passwd->pw_comment = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+#endif
+ passwd->pw_gecos = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ passwd->pw_dir = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ passwd->pw_shell = buf;
+ buf += strlen (buf) + 1;
+ if (buf - org > len)
+ return -1;
+
+ return 0;
+}
diff --git a/current/lib/rad64.c b/current/lib/rad64.c
new file mode 100644
index 00000000..249a71e1
--- /dev/null
+++ b/current/lib/rad64.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1989 - 1992, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: rad64.c,v 1.5 2000/08/26 18:27:17 marekm Exp $")
+
+/*
+ * c64i - convert a radix 64 character to an integer
+ */
+
+int
+c64i(int c)
+{
+ if (c == '.')
+ return (0);
+
+ if (c == '/')
+ return (1);
+
+ if (c >= '0' && c <= '9')
+ return (c - '0' + 2);
+
+ if (c >= 'A' && c <= 'Z')
+ return (c - 'A' + 12);
+
+ if (c >= 'a' && c <= 'z')
+ return (c - 'a' + 38);
+ else
+ return (-1);
+}
+
+/*
+ * i64c - convert an integer to a radix 64 character
+ */
+
+int
+i64c(int i)
+{
+ if (i <= 0)
+ return ('.');
+
+ if (i == 1)
+ return ('/');
+
+ if (i >= 2 && i < 12)
+ return ('0' - 2 + i);
+
+ if (i >= 12 && i < 38)
+ return ('A' - 12 + i);
+
+ if (i >= 38 && i < 63)
+ return ('a' - 38 + i);
+
+ return ('z');
+}
+
+#ifndef HAVE_A64L
+
+/*
+ * l64a - convert a long to a string of radix 64 characters
+ */
+
+char *
+l64a(long l)
+{
+ static char buf[8];
+ int i = 0;
+
+ if (l < 0L)
+ return ((char *) 0);
+
+ do {
+ buf[i++] = i64c ((int) (l % 64));
+ buf[i] = '\0';
+ } while (l /= 64L, l > 0 && i < 6);
+
+ return (buf);
+}
+
+/*
+ * a64l - convert a radix 64 string to a long integer
+ */
+
+long
+a64l(const char *s)
+{
+ int i;
+ long value;
+ long shift = 0;
+
+ for (i = 0, value = 0L;i < 6 && *s;s++) {
+ value += (c64i ((int) *s) << shift);
+ shift += 6;
+ }
+ return (value);
+}
+
+#endif /* !HAVE_A64L */
diff --git a/current/lib/rcsid.h b/current/lib/rcsid.h
new file mode 100644
index 00000000..3869afc1
--- /dev/null
+++ b/current/lib/rcsid.h
@@ -0,0 +1,22 @@
+/*
+ * $Id: rcsid.h,v 1.2 1999/06/07 16:40:44 marekm Exp $
+ */
+#define PKG_VER " $Package: " PACKAGE " $ $Version: " VERSION " $ "
+#if defined(NO_RCSID) || defined(lint)
+#define RCSID(x) /* empty */
+#else
+#if __STDC__
+/*
+ * This function is never called from anywhere, but it calls itself
+ * recursively only to fool gcc to not generate warnings :-).
+ */
+static const char *rcsid(const char *);
+#define RCSID(x) \
+ static const char *rcsid(const char *s) { \
+ return rcsid(x); }
+#else /* ! __STDC__ */
+#define RCSID(x) \
+ static char *rcsid(s) char *s; { \
+ return rcsid(x); }
+#endif /* ! __STDC__ */
+#endif
diff --git a/current/lib/rename.c b/current/lib/rename.c
new file mode 100644
index 00000000..d693d794
--- /dev/null
+++ b/current/lib/rename.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1993 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: rename.c,v 1.3 1997/12/07 23:26:57 marekm Exp $")
+
+#include "defines.h"
+#include <sys/stat.h>
+#include <errno.h>
+
+/*
+ * rename - rename a file to another name
+ *
+ * rename is provided for systems which do not include the rename()
+ * system call.
+ */
+
+int
+rename(const char *begin, const char *end)
+{
+ struct stat s1, s2;
+ extern int errno;
+ int orig_err = errno;
+
+ if (stat (begin, &s1))
+ return -1;
+
+ if (stat (end, &s2)) {
+ errno = orig_err;
+ } else {
+
+ /*
+ * See if this is a cross-device link. We do this to
+ * insure that the link below has a chance of working.
+ */
+
+ if (s1.st_dev != s2.st_dev) {
+ errno = EXDEV;
+ return -1;
+ }
+
+ /*
+ * See if we can unlink the existing destination
+ * file. If the unlink works the directory is writable,
+ * so there is no need here to figure that out.
+ */
+
+ if (unlink (end))
+ return -1;
+ }
+
+ /*
+ * Now just link the original name to the final name. If there
+ * was no file previously, this link will fail if the target
+ * directory isn't writable. The unlink will fail if the source
+ * directory isn't writable, but life stinks ...
+ */
+
+ if (link (begin, end) || unlink (begin))
+ return -1;
+
+ return 0;
+}
diff --git a/current/lib/rmdir.c b/current/lib/rmdir.c
new file mode 100644
index 00000000..d6a57508
--- /dev/null
+++ b/current/lib/rmdir.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <fcntl.h>
+
+#include "rcsid.h"
+RCSID("$Id: rmdir.c,v 1.4 1998/01/29 23:22:31 marekm Exp $")
+
+/*
+ * rmdir - remove a directory
+ *
+ * rmdir is provided for systems which do not include the rmdir()
+ * system call.
+ */
+
+int
+rmdir(const char *dir)
+{
+ int status;
+
+ if (fork()) {
+ while (wait(&status) != -1)
+ ;
+
+ return status >> 8;
+ }
+ close(2);
+ open("/dev/null", O_WRONLY);
+ execl("/bin/rmdir", "rmdir", dir, 0);
+ _exit(127);
+ /*NOTREACHED*/
+}
diff --git a/current/lib/sgetgrent.c b/current/lib/sgetgrent.c
new file mode 100644
index 00000000..daa5fbe2
--- /dev/null
+++ b/current/lib/sgetgrent.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: sgetgrent.c,v 1.4 1998/04/02 21:51:45 marekm Exp $")
+
+#include <stdio.h>
+#include <grp.h>
+#include "defines.h"
+
+#define NFIELDS 4
+
+/*
+ * list - turn a comma-separated string into an array of (char *)'s
+ *
+ * list() converts the comma-separated list of member names into
+ * an array of character pointers.
+ *
+ * WARNING: I profiled this once with and without strchr() calls
+ * and found that using a register variable and an explicit loop
+ * works best. For large /etc/group files, this is a major win.
+ *
+ * FINALLY added dynamic allocation. Still need to fix sgetsgent().
+ * --marekm
+ */
+
+static char **
+list(char *s)
+{
+ static char **members = 0;
+ static int size = 0; /* max members + 1 */
+ int i;
+ char **rbuf;
+
+ i = 0;
+ for (;;) {
+ /* check if there is room for another pointer (to a group
+ member name, or terminating NULL). */
+ if (i >= size) {
+ size = i + 100; /* at least: i + 1 */
+ if (members) {
+ rbuf = realloc(members, size * sizeof(char *));
+ } else {
+ /* for old (before ANSI C) implementations of
+ realloc() that don't handle NULL properly */
+ rbuf = malloc(size * sizeof(char *));
+ }
+ if (!rbuf) {
+ if (members)
+ free(members);
+ members = 0;
+ size = 0;
+ return (char **) 0;
+ }
+ members = rbuf;
+ }
+ if (!s || s[0] == '\0')
+ break;
+ members[i++] = s;
+ while (*s && *s != ',')
+ s++;
+ if (*s)
+ *s++ = '\0';
+ }
+ members[i] = (char *) 0;
+ return members;
+}
+
+
+struct group *
+sgetgrent(const char *buf)
+{
+ static char *grpbuf = 0;
+ static size_t size = 0;
+ static char *grpfields[NFIELDS];
+ static struct group grent;
+ int i;
+ char *cp;
+
+ if (strlen(buf) + 1 > size) {
+ /* no need to use realloc() here - just free it and
+ allocate a larger block */
+ if (grpbuf)
+ free(grpbuf);
+ size = strlen(buf) + 1000; /* at least: strlen(buf) + 1 */
+ grpbuf = malloc(size);
+ if (!grpbuf) {
+ size = 0;
+ return 0;
+ }
+ }
+ strcpy(grpbuf, buf);
+
+ if ((cp = strrchr(grpbuf, '\n')))
+ *cp = '\0';
+
+ for (cp = grpbuf, i = 0; i < NFIELDS && cp; i++) {
+ grpfields[i] = cp;
+ if ((cp = strchr(cp, ':')))
+ *cp++ = 0;
+ }
+ if (i < (NFIELDS-1) || *grpfields[2] == '\0')
+ return 0;
+ grent.gr_name = grpfields[0];
+ grent.gr_passwd = grpfields[1];
+ grent.gr_gid = atoi(grpfields[2]);
+ grent.gr_mem = list(grpfields[3]);
+ if (!grent.gr_mem)
+ return (struct group *) 0; /* out of memory */
+
+ return &grent;
+}
diff --git a/current/lib/sgetpwent.c b/current/lib/sgetpwent.c
new file mode 100644
index 00000000..993f3c97
--- /dev/null
+++ b/current/lib/sgetpwent.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: sgetpwent.c,v 1.5 1998/04/02 21:51:46 marekm Exp $")
+
+#include <sys/types.h>
+#include "defines.h"
+#include <stdio.h>
+#include <pwd.h>
+
+#define NFIELDS 7
+
+/*
+ * sgetpwent - convert a string to a (struct passwd)
+ *
+ * sgetpwent() parses a string into the parts required for a password
+ * structure. Strict checking is made for the UID and GID fields and
+ * presence of the correct number of colons. Any failing tests result
+ * in a NULL pointer being returned.
+ *
+ * NOTE: This function uses hard-coded string scanning functions for
+ * performance reasons. I am going to come up with some conditional
+ * compilation glarp to improve on this in the future.
+ */
+
+struct passwd *
+sgetpwent(const char *buf)
+{
+ static struct passwd pwent;
+ static char pwdbuf[1024];
+ register int i;
+ register char *cp;
+ char *ep;
+ char *fields[NFIELDS];
+
+ /*
+ * Copy the string to a static buffer so the pointers into
+ * the password structure remain valid.
+ */
+
+ if (strlen(buf) >= sizeof pwdbuf)
+ return 0; /* fail if too long */
+ strcpy(pwdbuf, buf);
+
+ /*
+ * Save a pointer to the start of each colon separated
+ * field. The fields are converted into NUL terminated strings.
+ */
+
+ for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
+ fields[i] = cp;
+ while (*cp && *cp != ':')
+ ++cp;
+
+ if (*cp)
+ *cp++ = '\0';
+ else
+ cp = 0;
+ }
+
+ /*
+ * There must be exactly NFIELDS colon separated fields or
+ * the entry is invalid. Also, the UID and GID must be non-blank.
+ */
+
+ if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
+ return 0;
+
+ /*
+ * Each of the fields is converted the appropriate data type
+ * and the result assigned to the password structure. If the
+ * UID or GID does not convert to an integer value, a NULL
+ * pointer is returned.
+ */
+
+ pwent.pw_name = fields[0];
+ pwent.pw_passwd = fields[1];
+ if (fields[2][0] == '\0' ||
+ ((pwent.pw_uid = strtol (fields[2], &ep, 10)) == 0 && *ep)) {
+ return 0;
+ }
+ if (fields[3][0] == '\0' ||
+ ((pwent.pw_gid = strtol (fields[3], &ep, 10)) == 0 && *ep)) {
+ return 0;
+ }
+#ifdef ATT_AGE
+ cp = pwent.pw_passwd;
+ while (*cp && *cp != ',')
+ ++cp;
+
+ if (*cp) {
+ *cp++ = '\0';
+ pwent.pw_age = cp;
+ } else {
+ cp = 0;
+ pwent.pw_age = "";
+ }
+#endif
+ pwent.pw_gecos = fields[4];
+#ifdef ATT_COMMENT
+ pwent.pw_comment = "";
+#endif
+ pwent.pw_dir = fields[5];
+ pwent.pw_shell = fields[6];
+
+ return &pwent;
+}
diff --git a/current/lib/sgetspent.c b/current/lib/sgetspent.c
new file mode 100644
index 00000000..1860075f
--- /dev/null
+++ b/current/lib/sgetspent.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef SHADOWPWD /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: sgetspent.c,v 1.5 1998/04/02 21:51:47 marekm Exp $")
+
+#include <sys/types.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <stdio.h>
+
+#define FIELDS 9
+#define OFIELDS 5
+
+/*
+ * sgetspent - convert string in shadow file format to (struct spwd *)
+ */
+
+struct spwd *
+sgetspent(const char *string)
+{
+ static char spwbuf[1024];
+ static struct spwd spwd;
+ char *fields[FIELDS];
+ char *cp;
+ char *cpp;
+ int i;
+
+ /*
+ * Copy string to local buffer. It has to be tokenized and we
+ * have to do that to our private copy.
+ */
+
+ if (strlen(string) >= sizeof spwbuf)
+ return 0; /* fail if too long */
+ strcpy(spwbuf, string);
+
+ if ((cp = strrchr (spwbuf, '\n')))
+ *cp = '\0';
+
+ /*
+ * Tokenize the string into colon separated fields. Allow up to
+ * FIELDS different fields.
+ */
+
+ for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) {
+ fields[i] = cp;
+ while (*cp && *cp != ':')
+ cp++;
+
+ if (*cp)
+ *cp++ = '\0';
+ }
+
+ /*
+ * It is acceptable for the last SVR4 field to be blank. This
+ * results in the loop being terminated early. In which case,
+ * we just make the last field be blank and be done with it.
+ */
+
+ if (i == (FIELDS-1))
+ fields[i++] = cp;
+
+ if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
+ return 0;
+
+ /*
+ * Start populating the structure. The fields are all in
+ * static storage, as is the structure we pass back.
+ */
+
+ spwd.sp_namp = fields[0];
+ spwd.sp_pwdp = fields[1];
+
+ /*
+ * Get the last changed date. For all of the integer fields,
+ * we check for proper format. It is an error to have an
+ * incorrectly formatted number.
+ */
+
+ if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[2][0] == '\0')
+ spwd.sp_lstchg = -1;
+
+ /*
+ * Get the minimum period between password changes.
+ */
+
+ if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[3][0] == '\0')
+ spwd.sp_min = -1;
+
+ /*
+ * Get the maximum number of days a password is valid.
+ */
+
+ if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[4][0] == '\0')
+ spwd.sp_max = -1;
+
+ /*
+ * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
+ * formatted file), initialize the other field members to -1.
+ */
+
+#if 0 /* SVR4 */
+ if (i == OFIELDS)
+ return 0;
+#else
+ if (i == OFIELDS) {
+ spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
+ spwd.sp_flag = -1;
+
+ return &spwd;
+ }
+#endif
+
+ /*
+ * The rest of the fields are mandatory for SVR4, but optional
+ * for anything else. However, if one is present the others
+ * must be as well.
+ */
+
+ /*
+ * Get the number of days of password expiry warning.
+ */
+
+ if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[5][0] == '\0')
+ spwd.sp_warn = -1;
+
+ /*
+ * Get the number of days of inactivity before an account is
+ * disabled.
+ */
+
+ if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[6][0] == '\0')
+ spwd.sp_inact = -1;
+
+ /*
+ * Get the number of days after the epoch before the account is
+ * set to expire.
+ */
+
+ if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[7][0] == '\0')
+ spwd.sp_expire = -1;
+
+ /*
+ * This field is reserved for future use. But it isn't supposed
+ * to have anything other than a valid integer in it.
+ */
+
+ if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
+ return 0;
+ } else if (fields[8][0] == '\0')
+ spwd.sp_flag = -1;
+
+ return (&spwd);
+}
+#endif /*}*/
diff --git a/current/lib/sgroupio.c b/current/lib/sgroupio.c
new file mode 100644
index 00000000..3bf2a087
--- /dev/null
+++ b/current/lib/sgroupio.c
@@ -0,0 +1,212 @@
+
+#include <config.h>
+
+#ifdef SHADOWGRP
+
+#include "rcsid.h"
+RCSID("$Id: sgroupio.c,v 1.11 2000/09/02 18:40:43 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include "commonio.h"
+#include "sgroupio.h"
+
+extern int putsgent(const struct sgrp *, FILE *);
+extern struct sgrp *sgetsgent(const char *);
+
+struct sgrp *
+__sgr_dup(const struct sgrp *sgent)
+{
+ struct sgrp *sg;
+ int i;
+
+ if (!(sg = (struct sgrp *) malloc(sizeof *sg)))
+ return NULL;
+ *sg = *sgent;
+ if (!(sg->sg_name = strdup(sgent->sg_name)))
+ return NULL;
+ if (!(sg->sg_passwd = strdup(sgent->sg_passwd)))
+ return NULL;
+
+ for (i = 0; sgent->sg_adm[i]; i++)
+ ;
+ sg->sg_adm = (char **) malloc((i + 1) * sizeof(char *));
+ if (!sg->sg_adm)
+ return NULL;
+ for (i = 0; sgent->sg_adm[i]; i++) {
+ sg->sg_adm[i] = strdup(sgent->sg_adm[i]);
+ if (!sg->sg_adm[i])
+ return NULL;
+ }
+ sg->sg_adm[i] = NULL;
+
+ for (i = 0; sgent->sg_mem[i]; i++)
+ ;
+ sg->sg_mem = (char **) malloc((i + 1) * sizeof(char *));
+ if (!sg->sg_mem)
+ return NULL;
+ for (i = 0; sgent->sg_mem[i]; i++) {
+ sg->sg_mem[i] = strdup(sgent->sg_mem[i]);
+ if (!sg->sg_mem[i])
+ return NULL;
+ }
+ sg->sg_mem[i] = NULL;
+
+ return sg;
+}
+
+static void *
+gshadow_dup(const void *ent)
+{
+ const struct sgrp *sg = ent;
+ return __sgr_dup(sg);
+}
+
+static void
+gshadow_free(void *ent)
+{
+ struct sgrp *sg = ent;
+
+ free(sg->sg_name);
+ free(sg->sg_passwd);
+ while(*(sg->sg_adm)) {
+ free(*(sg->sg_adm));
+ sg->sg_adm++;
+ }
+ while(*(sg->sg_mem)) {
+ free(*(sg->sg_mem));
+ sg->sg_mem++;
+ }
+ free(sg);
+}
+
+static const char *
+gshadow_getname(const void *ent)
+{
+ const struct sgrp *gr = ent;
+ return gr->sg_name;
+}
+
+static void *
+gshadow_parse(const char *line)
+{
+ return (void *) sgetsgent(line);
+}
+
+static int
+gshadow_put(const void *ent, FILE *file)
+{
+ const struct sgrp *sg = ent;
+ return (putsgent(sg, file) == -1) ? -1 : 0;
+}
+
+static struct commonio_ops gshadow_ops = {
+ gshadow_dup,
+ gshadow_free,
+ gshadow_getname,
+ gshadow_parse,
+ gshadow_put,
+ fgetsx,
+ fputsx
+};
+
+static struct commonio_db gshadow_db = {
+ SGROUP_FILE, /* filename */
+ &gshadow_ops, /* ops */
+ NULL, /* fp */
+ NULL, /* head */
+ NULL, /* tail */
+ NULL, /* cursor */
+ 0, /* changed */
+ 0, /* isopen */
+ 0, /* locked */
+ 0 /* readonly */
+};
+
+int
+sgr_name(const char *filename)
+{
+ return commonio_setname(&gshadow_db, filename);
+}
+
+int
+sgr_file_present(void)
+{
+ return commonio_present(&gshadow_db);
+}
+
+int
+sgr_lock(void)
+{
+ return commonio_lock(&gshadow_db);
+}
+
+int
+sgr_open(int mode)
+{
+ return commonio_open(&gshadow_db, mode);
+}
+
+const struct sgrp *
+sgr_locate(const char *name)
+{
+ return commonio_locate(&gshadow_db, name);
+}
+
+int
+sgr_update(const struct sgrp *sg)
+{
+ return commonio_update(&gshadow_db, (const void *) sg);
+}
+
+int
+sgr_remove(const char *name)
+{
+ return commonio_remove(&gshadow_db, name);
+}
+
+int
+sgr_rewind(void)
+{
+ return commonio_rewind(&gshadow_db);
+}
+
+const struct sgrp *
+sgr_next(void)
+{
+ return commonio_next(&gshadow_db);
+}
+
+int
+sgr_close(void)
+{
+ return commonio_close(&gshadow_db);
+}
+
+int
+sgr_unlock(void)
+{
+ return commonio_unlock(&gshadow_db);
+}
+
+void
+__sgr_set_changed(void)
+{
+ gshadow_db.changed = 1;
+}
+
+struct commonio_entry *
+__sgr_get_head(void)
+{
+ return gshadow_db.head;
+}
+
+void
+__sgr_del_entry(const struct commonio_entry *ent)
+{
+ commonio_del_entry(&gshadow_db, ent);
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif
diff --git a/current/lib/sgroupio.h b/current/lib/sgroupio.h
new file mode 100644
index 00000000..e9c93bf6
--- /dev/null
+++ b/current/lib/sgroupio.h
@@ -0,0 +1,13 @@
+extern struct sgrp *__sgr_dup(const struct sgrp *);
+extern void __sgr_set_changed(void);
+extern int sgr_close(void);
+extern int sgr_file_present(void);
+extern const struct sgrp *sgr_locate(const char *);
+extern int sgr_lock(void);
+extern int sgr_name(const char *);
+extern const struct sgrp *sgr_next(void);
+extern int sgr_open(int);
+extern int sgr_remove(const char *);
+extern int sgr_rewind(void);
+extern int sgr_unlock(void);
+extern int sgr_update(const struct sgrp *);
diff --git a/current/lib/shadow.c b/current/lib/shadow.c
new file mode 100644
index 00000000..76179d3a
--- /dev/null
+++ b/current/lib/shadow.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+/* Newer versions of Linux libc already have shadow support. */
+#if defined(SHADOWPWD) && !defined(HAVE_GETSPNAM) /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: shadow.c,v 1.6 1998/01/29 23:22:32 marekm Exp $")
+
+#include <sys/types.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <stdio.h>
+
+#ifdef NDBM
+#include <ndbm.h>
+#include <fcntl.h>
+DBM *sp_dbm;
+int sp_dbm_mode = -1;
+static int dbmopened;
+static int dbmerror;
+#endif
+
+#ifdef USE_NIS
+static int nis_used;
+static int nis_ignore;
+static enum { native, start, middle, native2 } nis_state;
+static int nis_bound;
+static char *nis_domain;
+static char *nis_key;
+static int nis_keylen;
+static char *nis_val;
+static int nis_vallen;
+#define IS_NISCHAR(c) ((c)=='+')
+#endif
+
+static FILE *shadow;
+static char spwbuf[BUFSIZ];
+static struct spwd spwd;
+
+#define FIELDS 9
+#define OFIELDS 5
+
+#ifdef USE_NIS
+
+/*
+ * __setspNIS - turn on or off NIS searches
+ */
+
+void
+__setspNIS(int flag)
+{
+ nis_ignore = ! flag;
+
+ if (nis_ignore)
+ nis_used = 0;
+}
+
+/*
+ * bind_nis - bind to NIS server
+ */
+
+static int
+bind_nis(void)
+{
+ if (yp_get_default_domain (&nis_domain))
+ return -1;
+
+ nis_bound = 1;
+ return 0;
+}
+#endif
+
+/*
+ * setspent - initialize access to shadow text and DBM files
+ */
+
+void
+setspent(void)
+{
+ if (shadow)
+ rewind(shadow);
+ else
+ shadow = fopen(SHADOW_FILE, "r");
+
+#ifdef USE_NIS
+ nis_state = native;
+#endif
+
+ /*
+ * Attempt to open the DBM files if they have never been opened
+ * and an error has never been returned.
+ */
+
+#ifdef NDBM
+ if (! dbmerror && ! dbmopened) {
+ int mode;
+ char dbmfiles[BUFSIZ];
+
+ strcpy (dbmfiles, SHADOW_PAG_FILE);
+
+ if (sp_dbm_mode == -1)
+ mode = O_RDWR;
+ else
+ mode = (sp_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY;
+
+ if (! (sp_dbm = dbm_open (SHADOW_FILE, mode, 0)))
+ dbmerror = 1;
+ else
+ dbmopened = 1;
+ }
+#endif
+}
+
+/*
+ * endspent - terminate access to shadow text and DBM files
+ */
+
+void
+endspent(void)
+{
+ if (shadow)
+ (void) fclose (shadow);
+
+ shadow = (FILE *) 0;
+#ifdef NDBM
+ if (dbmopened && sp_dbm) {
+ dbm_close (sp_dbm);
+ sp_dbm = 0;
+ }
+ dbmopened = 0;
+ dbmerror = 0;
+#endif
+}
+
+/*
+ * my_sgetspent - convert string in shadow file format to (struct spwd *)
+ */
+
+static struct spwd *
+my_sgetspent(const char *string)
+{
+ char *fields[FIELDS];
+ char *cp;
+ char *cpp;
+ int i;
+
+ /*
+ * Copy string to local buffer. It has to be tokenized and we
+ * have to do that to our private copy.
+ */
+
+ if (strlen(string) >= sizeof spwbuf)
+ return 0;
+ strcpy(spwbuf, string);
+
+ if ((cp = strrchr (spwbuf, '\n')))
+ *cp = '\0';
+
+ /*
+ * Tokenize the string into colon separated fields. Allow up to
+ * FIELDS different fields.
+ */
+
+ for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) {
+ fields[i] = cp;
+ while (*cp && *cp != ':')
+ cp++;
+
+ if (*cp)
+ *cp++ = '\0';
+ }
+
+ /*
+ * It is acceptable for the last SVR4 field to be blank. This
+ * results in the loop being terminated early. In which case,
+ * we just make the last field be blank and be done with it.
+ */
+
+ if (i == (FIELDS-1))
+ fields[i++] = cp;
+
+ if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
+ return 0;
+
+ /*
+ * Start populating the structure. The fields are all in
+ * static storage, as is the structure we pass back. If we
+ * ever see a name with '+' as the first character, we try
+ * to turn on NIS processing.
+ */
+
+ spwd.sp_namp = fields[0];
+#ifdef USE_NIS
+ if (IS_NISCHAR (fields[0][0]))
+ nis_used = 1;
+#endif
+ spwd.sp_pwdp = fields[1];
+
+ /*
+ * Get the last changed date. For all of the integer fields,
+ * we check for proper format. It is an error to have an
+ * incorrectly formatted number, unless we are using NIS.
+ */
+
+ if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_lstchg = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[2][0] == '\0')
+ spwd.sp_lstchg = -1;
+
+ /*
+ * Get the minimum period between password changes.
+ */
+
+ if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_min = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[3][0] == '\0')
+ spwd.sp_min = -1;
+
+ /*
+ * Get the maximum number of days a password is valid.
+ */
+
+ if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_max = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[4][0] == '\0')
+ spwd.sp_max = -1;
+
+ /*
+ * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
+ * formatted file), initialize the other field members to -1.
+ */
+
+#if 0 /* SVR4 */
+ if (i == OFIELDS)
+ return 0;
+#else
+ if (i == OFIELDS) {
+ spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
+ spwd.sp_flag = -1;
+
+ return &spwd;
+ }
+#endif
+
+ /*
+ * The rest of the fields are mandatory for SVR4, but optional
+ * for anything else. However, if one is present the others
+ * must be as well.
+ */
+
+ /*
+ * Get the number of days of password expiry warning.
+ */
+
+ if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_warn = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[5][0] == '\0')
+ spwd.sp_warn = -1;
+
+ /*
+ * Get the number of days of inactivity before an account is
+ * disabled.
+ */
+
+ if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_inact = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[6][0] == '\0')
+ spwd.sp_inact = -1;
+
+ /*
+ * Get the number of days after the epoch before the account is
+ * set to expire.
+ */
+
+ if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_expire = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[7][0] == '\0')
+ spwd.sp_expire = -1;
+
+ /*
+ * This field is reserved for future use. But it isn't supposed
+ * to have anything other than a valid integer in it.
+ */
+
+ if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
+#ifdef USE_NIS
+ if (! nis_used)
+ return 0;
+ else
+ spwd.sp_flag = -1;
+#else
+ return 0;
+#endif
+ } else if (fields[8][0] == '\0')
+ spwd.sp_flag = -1;
+
+ return (&spwd);
+}
+
+/*
+ * fgetspent - get an entry from a /etc/shadow formatted stream
+ */
+
+struct spwd *
+fgetspent(FILE *fp)
+{
+ char buf[BUFSIZ];
+ char *cp;
+
+ if (! fp)
+ return (0);
+
+#ifdef USE_NIS
+ while (fgets (buf, sizeof buf, fp) != (char *) 0)
+#else
+ if (fgets (buf, sizeof buf, fp) != (char *) 0)
+#endif
+ {
+ if ((cp = strchr (buf, '\n')))
+ *cp = '\0';
+#ifdef USE_NIS
+ if (nis_ignore && IS_NISCHAR (buf[0]))
+ continue;
+#endif
+ return my_sgetspent(buf);
+ }
+ return 0;
+}
+
+/*
+ * getspent - get a (struct spwd *) from the current shadow file
+ */
+
+struct spwd *
+getspent(void)
+{
+#ifdef USE_NIS
+ int nis_1_user = 0;
+ struct spwd *val;
+ char buf[BUFSIZ];
+#endif
+ if (! shadow)
+ setspent ();
+
+#ifdef USE_NIS
+again:
+ /*
+ * See if we are reading from the local file.
+ */
+
+ if (nis_state == native || nis_state == native2) {
+
+ /*
+ * Get the next entry from the shadow file. Return NULL
+ * right away if there is none.
+ */
+
+ if (! (val = fgetspent (shadow)))
+ return 0;
+
+ /*
+ * If this entry began with a NIS escape character, we have
+ * to see if this is just a single user, or if the entire
+ * map is being asked for.
+ */
+
+ if (IS_NISCHAR (val->sp_namp[0])) {
+ if (val->sp_namp[1])
+ nis_1_user = 1;
+ else
+ nis_state = start;
+ }
+
+ /*
+ * If this isn't a NIS user and this isn't an escape to go
+ * use a NIS map, it must be a regular local user.
+ */
+
+ if (nis_1_user == 0 && nis_state != start)
+ return val;
+
+ /*
+ * If this is an escape to use an NIS map, switch over to
+ * that bunch of code.
+ */
+
+ if (nis_state == start)
+ goto again;
+
+ /*
+ * NEEDSWORK. Here we substitute pieces-parts of this entry.
+ */
+
+ return 0;
+ } else {
+ if (nis_bound == 0) {
+ if (bind_nis ()) {
+ nis_state = native2;
+ goto again;
+ }
+ }
+ if (nis_state == start) {
+ if (yp_first (nis_domain, "shadow.bynam", &nis_key,
+ &nis_keylen, &nis_val, &nis_vallen)) {
+ nis_state = native2;
+ goto again;
+ }
+ nis_state = middle;
+ } else if (nis_state == middle) {
+ if (yp_next (nis_domain, "shadow.bynam", nis_key,
+ nis_keylen, &nis_key, &nis_keylen,
+ &nis_val, &nis_vallen)) {
+ nis_state = native2;
+ goto again;
+ }
+ }
+ return my_sgetspent(nis_val);
+ }
+#else
+ return (fgetspent (shadow));
+#endif
+}
+
+/*
+ * getspnam - get a shadow entry by name
+ */
+
+struct spwd *
+getspnam(const char *name)
+{
+ struct spwd *sp;
+#ifdef NDBM
+ datum key;
+ datum content;
+#endif
+#ifdef USE_NIS
+ char buf[BUFSIZ];
+ static char save_name[16];
+ int nis_disabled = 0;
+#endif
+
+ setspent ();
+
+#ifdef NDBM
+
+ /*
+ * If the DBM file are now open, create a key for this UID and
+ * try to fetch the entry from the database. A matching record
+ * will be unpacked into a static structure and returned to
+ * the user.
+ */
+
+ if (dbmopened) {
+ key.dsize = strlen (name);
+ key.dptr = (char *) name;
+
+ content = dbm_fetch (sp_dbm, key);
+ if (content.dptr != 0) {
+ memcpy (spwbuf, content.dptr, content.dsize);
+ spw_unpack (spwbuf, content.dsize, &spwd);
+ endspent();
+ return &spwd;
+ }
+ }
+#endif
+#ifdef USE_NIS
+ /*
+ * Search the shadow.byname map for this user.
+ */
+
+ if (! nis_ignore && ! nis_bound)
+ bind_nis ();
+
+ if (! nis_ignore && nis_bound) {
+ char *cp;
+
+ if (yp_match (nis_domain, "shadow.byname", name,
+ strlen (name), &nis_val, &nis_vallen) == 0) {
+
+ if (cp = strchr (nis_val, '\n'))
+ *cp = '\0';
+
+ nis_state = middle;
+ if ((sp = my_sgetspent(nis_val))) {
+ strcpy (save_name, sp->sp_namp);
+ nis_key = save_name;
+ nis_keylen = strlen (save_name);
+ }
+ endspent();
+ return sp;
+ } else
+ nis_state = native2;
+ }
+#endif
+#ifdef USE_NIS
+ /*
+ * NEEDSWORK -- this is a mess, and it is the same mess in the
+ * other three files. I can't just blindly turn off NIS because
+ * this might be the first pass through the local files. In
+ * that case, I never discover that NIS is present.
+ */
+
+ if (nis_used) {
+ nis_ignore++;
+ nis_disabled++;
+ }
+#endif
+ while ((sp = getspent ()) != (struct spwd *) 0) {
+ if (strcmp (name, sp->sp_namp) == 0)
+ break;
+ }
+#ifdef USE_NIS
+ if (nis_disabled)
+ nis_ignore--;
+#endif
+ endspent();
+ return (sp);
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif /*}*/
diff --git a/current/lib/shadow_.h b/current/lib/shadow_.h
new file mode 100644
index 00000000..ebb43802
--- /dev/null
+++ b/current/lib/shadow_.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1988 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _H_SHADOW
+#define _H_SHADOW
+
+/*
+ * This information is not derived from AT&T licensed sources. Posted
+ * to the USENET 11/88, and updated 11/90 with information from SVR4.
+ *
+ * $Id: shadow_.h,v 1.2 1997/05/01 23:14:48 marekm Exp $
+ */
+
+#ifdef ITI_AGING
+typedef time_t sptime;
+#else
+typedef long sptime;
+#endif
+
+/*
+ * Shadow password security file structure.
+ */
+
+struct spwd {
+ char *sp_namp; /* login name */
+ char *sp_pwdp; /* encrypted password */
+ sptime sp_lstchg; /* date of last change */
+ sptime sp_min; /* minimum number of days between changes */
+ sptime sp_max; /* maximum number of days between changes */
+ sptime sp_warn; /* number of days of warning before password
+ expires */
+ sptime sp_inact; /* number of days after password expires
+ until the account becomes unusable. */
+ sptime sp_expire; /* days since 1/1/70 until account expires */
+ unsigned long sp_flag; /* reserved for future use */
+};
+
+/*
+ * Shadow password security file functions.
+ */
+
+#include <stdio.h> /* for FILE */
+
+#if defined(__STDC__)
+struct spwd *getspent (void);
+struct spwd *getspnam (const char *);
+struct spwd *sgetspent (const char *);
+struct spwd *fgetspent (FILE *);
+void setspent (void);
+void endspent (void);
+int putspent (const struct spwd *, FILE *);
+#else
+struct spwd *getspent ();
+struct spwd *getspnam ();
+struct spwd *sgetspent ();
+struct spwd *fgetspent ();
+void setspent ();
+void endspent ();
+int putspent ();
+#endif
+
+#define SHADOW "/etc/shadow"
+#endif
diff --git a/current/lib/shadowio.c b/current/lib/shadowio.c
new file mode 100644
index 00000000..e6707cf2
--- /dev/null
+++ b/current/lib/shadowio.c
@@ -0,0 +1,171 @@
+
+#include <config.h>
+
+#ifdef SHADOWPWD
+
+#include "rcsid.h"
+RCSID("$Id: shadowio.c,v 1.12 2000/09/02 18:40:43 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#ifdef HAVE_SHADOW_H
+# include <shadow.h>
+#endif
+#include <stdio.h>
+
+#include "commonio.h"
+#include "shadowio.h"
+
+struct spwd *
+__spw_dup(const struct spwd *spent)
+{
+ struct spwd *sp;
+
+ if (!(sp = (struct spwd *) malloc(sizeof *sp)))
+ return NULL;
+ *sp = *spent;
+ if (!(sp->sp_namp = strdup(spent->sp_namp)))
+ return NULL;
+ if (!(sp->sp_pwdp = strdup(spent->sp_pwdp)))
+ return NULL;
+ return sp;
+}
+
+static void *
+shadow_dup(const void *ent)
+{
+ const struct spwd *sp = ent;
+ return __spw_dup(sp);
+}
+
+static void
+shadow_free(void *ent)
+{
+ struct spwd *sp = ent;
+
+ free(sp->sp_namp);
+ free(sp->sp_pwdp);
+ free(sp);
+}
+
+static const char *
+shadow_getname(const void *ent)
+{
+ const struct spwd *sp = ent;
+ return sp->sp_namp;
+}
+
+static void *
+shadow_parse(const char *line)
+{
+ return (void *) sgetspent(line);
+}
+
+static int
+shadow_put(const void *ent, FILE *file)
+{
+ const struct spwd *sp = ent;
+ return (putspent(sp, file) == -1) ? -1 : 0;
+}
+
+static struct commonio_ops shadow_ops = {
+ shadow_dup,
+ shadow_free,
+ shadow_getname,
+ shadow_parse,
+ shadow_put,
+ fgets,
+ fputs
+};
+
+static struct commonio_db shadow_db = {
+ SHADOW_FILE, /* filename */
+ &shadow_ops, /* ops */
+ NULL, /* fp */
+ NULL, /* head */
+ NULL, /* tail */
+ NULL, /* cursor */
+ 0, /* changed */
+ 0, /* isopen */
+ 0, /* locked */
+ 0 /* readonly */
+};
+
+int
+spw_name(const char *filename)
+{
+ return commonio_setname(&shadow_db, filename);
+}
+
+int
+spw_file_present(void)
+{
+ return commonio_present(&shadow_db);
+}
+
+int
+spw_lock(void)
+{
+ return commonio_lock(&shadow_db);
+}
+
+int
+spw_open(int mode)
+{
+ return commonio_open(&shadow_db, mode);
+}
+
+const struct spwd *
+spw_locate(const char *name)
+{
+ return commonio_locate(&shadow_db, name);
+}
+
+int
+spw_update(const struct spwd *sp)
+{
+ return commonio_update(&shadow_db, (const void *) sp);
+}
+
+int
+spw_remove(const char *name)
+{
+ return commonio_remove(&shadow_db, name);
+}
+
+int
+spw_rewind(void)
+{
+ return commonio_rewind(&shadow_db);
+}
+
+const struct spwd *
+spw_next(void)
+{
+ return commonio_next(&shadow_db);
+}
+
+int
+spw_close(void)
+{
+ return commonio_close(&shadow_db);
+}
+
+int
+spw_unlock(void)
+{
+ return commonio_unlock(&shadow_db);
+}
+
+struct commonio_entry *
+__spw_get_head(void)
+{
+ return shadow_db.head;
+}
+
+void
+__spw_del_entry(const struct commonio_entry *ent)
+{
+ commonio_del_entry(&shadow_db, ent);
+}
+#endif
diff --git a/current/lib/shadowio.h b/current/lib/shadowio.h
new file mode 100644
index 00000000..b3118d5c
--- /dev/null
+++ b/current/lib/shadowio.h
@@ -0,0 +1,13 @@
+extern struct spwd *__spw_dup(const struct spwd *);
+extern void __spw_set_changed(void);
+extern int spw_close(void);
+extern int spw_file_present(void);
+extern const struct spwd *spw_locate(const char *);
+extern int spw_lock(void);
+extern int spw_name(const char *);
+extern const struct spwd *spw_next(void);
+extern int spw_open(int);
+extern int spw_remove(const char *);
+extern int spw_rewind(void);
+extern int spw_unlock(void);
+extern int spw_update(const struct spwd *);
diff --git a/current/lib/snprintf.c b/current/lib/snprintf.c
new file mode 100644
index 00000000..c62366d9
--- /dev/null
+++ b/current/lib/snprintf.c
@@ -0,0 +1,320 @@
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh. This sort of thing is always nasty do deal with. Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length. This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ **************************************************************/
+
+/* $XFree86: xc/lib/misc/snprintf.c,v 3.0 1996/08/26 06:19:23 dawes Exp $ */
+
+#include <ctype.h>
+#include "snprintf.h"
+
+static void dopr();
+static char *end;
+
+/* varargs declarations: */
+
+#if defined(HAVE_STDARG_H)
+# include <stdarg.h>
+# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
+# define VA_LOCAL_DECL va_list ap;
+# define VA_START(f) va_start(ap, f)
+# define VA_SHIFT(v,t) ; /* no-op for ANSI */
+# define VA_END va_end(ap)
+#else
+# if defined(HAVE_VARARGS_H)
+# include <varargs.h>
+# undef HAVE_STDARGS
+# define VA_LOCAL_DECL va_list ap;
+# define VA_START(f) va_start(ap) /* f is ignored! */
+# define VA_SHIFT(v,t) v = va_arg(ap,t)
+# define VA_END va_end(ap)
+# else
+/*XX ** NO VARARGS ** XX*/
+# endif
+#endif
+
+#ifdef HAVE_STDARGS
+int snprintf (char *str, size_t count, const char *fmt, ...);
+int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+#else
+int snprintf ();
+int vsnprintf ();
+#endif
+
+int
+vsnprintf(str, count, fmt, args)
+ char *str;
+ size_t count;
+ const char *fmt;
+ va_list args;
+{
+ str[0] = 0;
+ end = str+count-1;
+ dopr( str, fmt, args );
+ if( count>0 ){
+ end[0] = 0;
+ }
+ return(strlen(str));
+}
+
+/* VARARGS3 */
+#ifdef HAVE_STDARGS
+int
+snprintf (char *str,size_t count,const char *fmt,...)
+#else
+int
+snprintf (va_alist) va_dcl
+#endif
+{
+#ifndef HAVE_STDARGS
+ char *str;
+ size_t count;
+ char *fmt;
+#endif
+ VA_LOCAL_DECL
+
+ VA_START (fmt);
+ VA_SHIFT (str, char *);
+ VA_SHIFT (count, size_t );
+ VA_SHIFT (fmt, char *);
+ (void) vsnprintf ( str, count, fmt, ap);
+ VA_END;
+ return( strlen( str ) );
+}
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+static void fmtstr(
+#if NeedFunctionPrototypes
+ char *value, int ljust, int len, int zpad
+#endif
+);
+
+static void fmtnum(
+#if NeedFunctionPrototypes
+ long value, int base, int dosign, int ljust, int len, int zpad
+#endif
+);
+
+static void dostr(
+#if NeedFunctionPrototypes
+ char *
+#endif
+);
+
+static char *output;
+
+static void dopr_outch(
+#if NeedFunctionPrototypes
+ int c
+#endif
+);
+
+static void
+dopr( buffer, format, args )
+ char *buffer;
+ char *format;
+ va_list args;
+{
+ int ch;
+ long value;
+ int longflag = 0;
+ char *strvalue;
+ int ljust;
+ int len;
+ int zpad;
+
+ output = buffer;
+ while( (ch = *format++) ){
+ switch( ch ){
+ case '%':
+ ljust = len = zpad = 0;
+ nextch:
+ ch = *format++;
+ switch( ch ){
+ case 0:
+ dostr( "**end of format**" );
+ return;
+ case '-': ljust = 1; goto nextch;
+ case '0': /* set zero padding if len not set */
+ if(len==0) zpad = '0';
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ len = len*10 + ch - '0';
+ goto nextch;
+ case 'l': longflag = 1; goto nextch;
+ case 'u': case 'U':
+ /*fmtnum(value,base,dosign,ljust,len,zpad) */
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 10,0, ljust, len, zpad ); break;
+ case 'o': case 'O':
+ /*fmtnum(value,base,dosign,ljust,len,zpad) */
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 8,0, ljust, len, zpad ); break;
+ case 'd': case 'D':
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 10,1, ljust, len, zpad ); break;
+ case 'x':
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 16,0, ljust, len, zpad ); break;
+ case 'X':
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value,-16,0, ljust, len, zpad ); break;
+ case 's':
+ strvalue = va_arg( args, char *);
+ fmtstr( strvalue,ljust,len,zpad ); break;
+ case 'c':
+ ch = va_arg( args, int );
+ dopr_outch( ch ); break;
+ case '%': dopr_outch( ch ); continue;
+ default:
+ dostr( "???????" );
+ }
+ longflag = 0;
+ break;
+ default:
+ dopr_outch( ch );
+ break;
+ }
+ }
+ *output = 0;
+}
+
+static void
+fmtstr( value, ljust, len, zpad )
+ char *value;
+ int ljust, len, zpad;
+{
+ int padlen, strlen; /* amount to pad */
+
+ if( value == 0 ){
+ value = "<NULL>";
+ }
+ for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
+ padlen = len - strlen;
+ if( padlen < 0 ) padlen = 0;
+ if( ljust ) padlen = -padlen;
+ while( padlen > 0 ) {
+ dopr_outch( ' ' );
+ --padlen;
+ }
+ dostr( value );
+ while( padlen < 0 ) {
+ dopr_outch( ' ' );
+ ++padlen;
+ }
+}
+
+static void
+fmtnum( value, base, dosign, ljust, len, zpad )
+ long value;
+ int base, dosign, ljust, len, zpad;
+{
+ int signvalue = 0;
+ unsigned long uvalue;
+ char convert[20];
+ int place = 0;
+ int padlen = 0; /* amount to pad */
+ int caps = 0;
+
+ /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
+ value, base, dosign, ljust, len, zpad )); */
+ uvalue = value;
+ if( dosign ){
+ if( value < 0 ) {
+ signvalue = '-';
+ uvalue = -value;
+ }
+ }
+ if( base < 0 ){
+ caps = 1;
+ base = -base;
+ }
+ do{
+ convert[place++] =
+ (caps? "0123456789ABCDEF":"0123456789abcdef")
+ [uvalue % (unsigned)base ];
+ uvalue = (uvalue / (unsigned)base );
+ }while(uvalue);
+ convert[place] = 0;
+ padlen = len - place;
+ if( padlen < 0 ) padlen = 0;
+ if( ljust ) padlen = -padlen;
+ /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
+ convert,place,signvalue,padlen)); */
+ if( zpad && padlen > 0 ){
+ if( signvalue ){
+ dopr_outch( signvalue );
+ --padlen;
+ signvalue = 0;
+ }
+ while( padlen > 0 ){
+ dopr_outch( zpad );
+ --padlen;
+ }
+ }
+ while( padlen > 0 ) {
+ dopr_outch( ' ' );
+ --padlen;
+ }
+ if( signvalue ) dopr_outch( signvalue );
+ while( place > 0 ) dopr_outch( convert[--place] );
+ while( padlen < 0 ){
+ dopr_outch( ' ' );
+ ++padlen;
+ }
+}
+
+static void
+dostr( str )
+ char *str;
+{
+ while(*str) dopr_outch(*str++);
+}
+
+static void
+dopr_outch( c )
+ int c;
+{
+ if( iscntrl(c) && c != '\n' && c != '\t' ){
+ c = '@' + (c & 0x1F);
+ if( end == 0 || output < end ){
+ *output++ = '^';
+ }
+ }
+ if( end == 0 || output < end ){
+ *output++ = c;
+ }
+}
diff --git a/current/lib/snprintf.h b/current/lib/snprintf.h
new file mode 100644
index 00000000..e900e31e
--- /dev/null
+++ b/current/lib/snprintf.h
@@ -0,0 +1,51 @@
+/* $XFree86: xc/lib/misc/snprintf.h,v 3.1 1996/08/26 14:42:33 dawes Exp $ */
+
+#ifndef SNPRINTF_H
+#define SNPRINTF_H
+
+#ifdef HAS_SNPRINTF
+#ifdef LIBXT
+#define _XtSnprintf snprintf
+#define _XtVsnprintf vsnprintf
+#endif
+#ifdef LIBX11
+#define _XSnprintf snprintf
+#define _XVsnprintf vsnprintf
+#endif
+#else /* !HAS_SNPRINTF */
+
+#ifdef LIBXT
+#define snprintf _XtSnprintf
+#define vsnprintf _XtVsnprintf
+#endif
+#ifdef LIBX11
+#define snprintf _XSnprintf
+#define vsnprintf _XVsnprintf
+#endif
+
+#if 1 /* the system might have no X11 headers. -MM */
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#else /* but we still need this... */
+#include <sys/types.h>
+/* adjust the following defines if necessary (pre-ANSI) */
+#define NeedFunctionPrototypes 1
+#define NeedVarargsPrototypes 1
+#endif
+
+#if NeedVarargsPrototypes
+#define HAVE_STDARG_H
+#endif
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+extern int snprintf (char *str, size_t count, const char *fmt, ...);
+extern int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+#else
+extern int snprintf ();
+extern int vsnprintf ();
+#endif
+
+#endif /* HAS_SNPRINTF */
+
+#endif /* SNPRINTF_H */
diff --git a/current/lib/spdbm.c b/current/lib/spdbm.c
new file mode 100644
index 00000000..317ea6b7
--- /dev/null
+++ b/current/lib/spdbm.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#if defined(SHADOWPWD) && defined(NDBM) /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: spdbm.c,v 1.3 1997/12/07 23:26:58 marekm Exp $")
+
+#include <string.h>
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <ndbm.h>
+extern DBM *sp_dbm;
+
+/*
+ * sp_dbm_update
+ *
+ * Updates the DBM password files, if they exist.
+ */
+
+int
+sp_dbm_update(struct spwd *sp)
+{
+ datum key;
+ datum content;
+ char data[BUFSIZ];
+ int len;
+ static int once;
+
+ if (! once) {
+ if (! sp_dbm)
+ setspent ();
+
+ once++;
+ }
+ if (! sp_dbm)
+ return 0;
+
+ len = spw_pack (sp, data);
+
+ content.dsize = len;
+ content.dptr = data;
+
+ key.dsize = strlen (sp->sp_namp);
+ key.dptr = sp->sp_namp;
+ if (dbm_store (sp_dbm, key, content, DBM_REPLACE))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * sp_dbm_remove
+ *
+ * Updates the DBM password files, if they exist.
+ */
+
+int
+sp_dbm_remove(char *user)
+{
+ datum key;
+ static int once;
+
+ if (! once) {
+ if (! sp_dbm)
+ setspent ();
+
+ once++;
+ }
+ if (! sp_dbm)
+ return 0;
+
+ key.dsize = strlen (user);
+ key.dptr = user;
+ if (dbm_delete (sp_dbm, key))
+ return 0;
+
+ return 1;
+}
+
+int
+sp_dbm_present(void)
+{
+ return (access(SHADOW_PAG_FILE, F_OK) == 0);
+}
+#endif /*} SHADOWPWD && NDBM */
diff --git a/current/lib/sppack.c b/current/lib/sppack.c
new file mode 100644
index 00000000..463f633a
--- /dev/null
+++ b/current/lib/sppack.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#ifdef SHADOWPWD /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: sppack.c,v 1.3 1997/12/07 23:26:58 marekm Exp $")
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "defines.h"
+
+int
+spw_pack(const struct spwd *spwd, char *buf)
+{
+ char *cp;
+
+ cp = buf;
+ strcpy (cp, spwd->sp_namp);
+ cp += strlen (cp) + 1;
+
+ strcpy (cp, spwd->sp_pwdp);
+ cp += strlen (cp) + 1;
+
+ memcpy (cp, &spwd->sp_min, sizeof spwd->sp_min);
+ cp += sizeof spwd->sp_min;
+
+ memcpy (cp, &spwd->sp_max, sizeof spwd->sp_max);
+ cp += sizeof spwd->sp_max;
+
+ memcpy (cp, &spwd->sp_lstchg, sizeof spwd->sp_lstchg);
+ cp += sizeof spwd->sp_lstchg;
+
+ memcpy (cp, &spwd->sp_warn, sizeof spwd->sp_warn);
+ cp += sizeof spwd->sp_warn;
+
+ memcpy (cp, &spwd->sp_inact, sizeof spwd->sp_inact);
+ cp += sizeof spwd->sp_inact;
+
+ memcpy (cp, &spwd->sp_expire, sizeof spwd->sp_expire);
+ cp += sizeof spwd->sp_expire;
+
+ memcpy (cp, &spwd->sp_flag, sizeof spwd->sp_flag);
+ cp += sizeof spwd->sp_flag;
+
+ return cp - buf;
+}
+
+int
+spw_unpack(char *buf, int len, struct spwd *spwd)
+{
+ char *org = buf;
+
+ spwd->sp_namp = buf;
+ buf += strlen (buf) + 1;
+
+ spwd->sp_pwdp = buf;
+ buf += strlen (buf) + 1;
+
+ memcpy (&spwd->sp_min, buf, sizeof spwd->sp_min);
+ buf += sizeof spwd->sp_min;
+
+ memcpy (&spwd->sp_max, buf, sizeof spwd->sp_max);
+ buf += sizeof spwd->sp_max;
+
+ memcpy (&spwd->sp_lstchg, buf, sizeof spwd->sp_lstchg);
+ buf += sizeof spwd->sp_lstchg;
+
+ memcpy (&spwd->sp_warn, buf, sizeof spwd->sp_warn);
+ buf += sizeof spwd->sp_warn;
+
+ memcpy (&spwd->sp_inact, buf, sizeof spwd->sp_inact);
+ buf += sizeof spwd->sp_inact;
+
+ memcpy (&spwd->sp_expire, buf, sizeof spwd->sp_expire);
+ buf += sizeof spwd->sp_expire;
+
+ memcpy (&spwd->sp_flag, buf, sizeof spwd->sp_flag);
+ buf += sizeof spwd->sp_flag;
+
+ if (buf - org > len)
+ return -1;
+
+ return 0;
+}
+#endif /*}*/
diff --git a/current/lib/strcasecmp.c b/current/lib/strcasecmp.c
new file mode 100644
index 00000000..414a47aa
--- /dev/null
+++ b/current/lib/strcasecmp.c
@@ -0,0 +1,25 @@
+#include <config.h>
+#include "defines.h"
+#include <ctype.h>
+
+#include "rcsid.h"
+RCSID("$Id: strcasecmp.c,v 1.1 1999/07/09 18:02:43 marekm Exp $")
+
+/*
+ * strcasecmp - compare strings, ignoring case
+ */
+
+char *
+strcasecmp(const char *s1, const char *s2)
+{
+ int ret;
+
+ for (;;) {
+ ret = tolower(*s1) - tolower(*s2);
+ if (ret || *s1 == '\0' || *s2 == '\0')
+ break;
+ s1++;
+ s2++;
+ }
+ return ret;
+}
diff --git a/current/lib/strdup.c b/current/lib/strdup.c
new file mode 100644
index 00000000..fe522b45
--- /dev/null
+++ b/current/lib/strdup.c
@@ -0,0 +1,16 @@
+#include <config.h>
+#include "defines.h"
+#include "rcsid.h"
+RCSID("$Id: strdup.c,v 1.2 1997/12/07 23:26:59 marekm Exp $")
+
+extern char *malloc();
+
+char *
+strdup(const char *str)
+{
+ char *s = malloc(strlen(str) + 1);
+
+ if (s)
+ strcpy(s, str);
+ return s;
+}
diff --git a/current/lib/strerror.c b/current/lib/strerror.c
new file mode 100644
index 00000000..184b1a46
--- /dev/null
+++ b/current/lib/strerror.c
@@ -0,0 +1,23 @@
+#include <config.h>
+#include <errno.h>
+#include "defines.h"
+#include "rcsid.h"
+RCSID("$Id: strerror.c,v 1.3 1998/12/28 20:34:39 marekm Exp $")
+
+#include <stdio.h>
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int err)
+{
+ static char unknown[80];
+
+ if (err >= 0 && err < sys_nerr)
+ return sys_errlist[err];
+
+ snprintf(unknown, sizeof unknown, _("Unknown error %d"), err);
+ errno = EINVAL;
+ return unknown;
+}
diff --git a/current/lib/strstr.c b/current/lib/strstr.c
new file mode 100644
index 00000000..b4fca453
--- /dev/null
+++ b/current/lib/strstr.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include "defines.h"
+
+#include "rcsid.h"
+RCSID("$Id: strstr.c,v 1.4 1998/01/29 23:22:32 marekm Exp $")
+
+/*
+ * strstr - find substring in string
+ */
+
+char *
+strstr(const char *string, const char *pattern)
+{
+ char *cp;
+ int len;
+
+ len = strlen (pattern);
+
+ for (cp = string;cp = strchr (cp, *pattern);) {
+ if (strncmp (cp, pattern, len) == 0)
+ return cp;
+
+ cp++;
+ }
+ return 0;
+}
diff --git a/current/lib/tcfsio.c b/current/lib/tcfsio.c
new file mode 100644
index 00000000..2649e0be
--- /dev/null
+++ b/current/lib/tcfsio.c
@@ -0,0 +1,90 @@
+
+#include <config.h>
+
+#ifdef HAVE_TCFS
+
+#include "prototypes.h"
+#include "defines.h"
+
+#ifdef TCFS_GDBM_SUPPORT
+#undef GDBM_SUPPORT
+#define GDBM_SUPPORT
+#endif
+
+#include <tcfslib.h>
+#include <stdio.h>
+
+#include "commonio.h"
+#include "tcfsio.h"
+
+static struct commonio_db tcfs_db = {
+ TCFSPWDFILE, /* filename */
+ NULL, /* ops */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+};
+
+int
+tcfs_file_present(void)
+{
+ return commonio_present(&tcfs_db);
+}
+
+int
+tcfs_lock(void)
+{
+ return commonio_lock(&tcfs_db);
+}
+
+int
+tcfs_open(int mode)
+{
+ return 1;
+/* return tcfs_open(); */
+}
+
+tcfspwdb *
+tcfs_locate(char *name)
+{
+ return tcfs_getpwnam(name, NULL);
+}
+
+int
+tcfs_update(char *user, struct tcfspwd *tcfspword)
+{
+ char *o, *p;
+
+ o=(char*)calloc(128,sizeof(char));
+ p=(char*)calloc(128,sizeof(char));
+ strcpy (o, tcfspword->tcfsorig);
+ strcpy (p, tcfspword->tcfspass);
+ return tcfs_chgkey(user,o,p);
+}
+
+int
+tcfs_remove(char *name)
+{
+ return tcfs_putpwnam(name, NULL, U_DEL);
+}
+
+int
+tcfs_close(void)
+{
+ return 1;
+/* return tcfs_close(&shadow_db); */
+}
+
+int
+tcfs_unlock(void)
+{
+ return commonio_unlock(&tcfs_db);
+}
+
+#endif
diff --git a/current/lib/tcfsio.h b/current/lib/tcfsio.h
new file mode 100644
index 00000000..3f53fca5
--- /dev/null
+++ b/current/lib/tcfsio.h
@@ -0,0 +1,14 @@
+struct tcfspwd {
+ char tcfspass[200]; /* new password */
+ char tcfsorig[200]; /* old password */
+};
+
+extern int tcfs_close(void);
+extern int tcfs_file_present(void);
+extern tcfspwdb *tcfs_locate(char *);
+extern int tcfs_lock(void);
+extern int tcfs_name(char *);
+extern int tcfs_open(int);
+extern int tcfs_remove(char *);
+extern int tcfs_unlock(void);
+extern int tcfs_update(char *, struct tcfspwd *);
diff --git a/current/lib/utent.c b/current/lib/utent.c
new file mode 100644
index 00000000..0b14d14c
--- /dev/null
+++ b/current/lib/utent.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1993 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_GETUTENT
+
+#include "defines.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+#ifndef lint
+static char rcsid[] = "$Id: utent.c,v 1.4 1998/01/29 23:22:32 marekm Exp $";
+#endif
+
+static int utmp_fd = -1;
+static struct utmp utmp_buf;
+
+/*
+ * setutent - open or rewind the utmp file
+ */
+
+void
+setutent(void)
+{
+ if (utmp_fd == -1)
+ if ((utmp_fd = open (_UTMP_FILE, O_RDWR)) == -1)
+ utmp_fd = open (_UTMP_FILE, O_RDONLY);
+
+ if (utmp_fd != -1)
+ lseek (utmp_fd, (off_t) 0L, SEEK_SET);
+}
+
+/*
+ * endutent - close the utmp file
+ */
+
+void
+endutent(void)
+{
+ if (utmp_fd != -1)
+ close (utmp_fd);
+
+ utmp_fd = -1;
+}
+
+/*
+ * getutent - get the next record from the utmp file
+ */
+
+struct utmp *
+getutent(void)
+{
+ if (utmp_fd == -1)
+ setutent ();
+
+ if (utmp_fd == -1)
+ return 0;
+
+ if (read (utmp_fd, &utmp_buf, sizeof utmp_buf) != sizeof utmp_buf)
+ return 0;
+
+ return &utmp_buf;
+}
+
+/*
+ * getutline - get the utmp entry matching ut_line
+ */
+
+struct utmp *
+getutline(const struct utmp *utent)
+{
+ struct utmp save;
+ struct utmp *new;
+
+ save = *utent;
+ while (new = getutent ())
+ if (strncmp (new->ut_line, save.ut_line, sizeof new->ut_line))
+ continue;
+ else
+ return new;
+
+ return (struct utmp *) 0;
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif
diff --git a/current/libmisc/Makefile.am b/current/libmisc/Makefile.am
new file mode 100644
index 00000000..21fe04cd
--- /dev/null
+++ b/current/libmisc/Makefile.am
@@ -0,0 +1,20 @@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+noinst_HEADERS = chkname.h failure.h getdate.h
+
+noinst_LIBRARIES = libmisc.a
+
+libdir = $(prefix)/lib
+localedir = $(datadir)/locale
+INCLUDES = -I$(top_srcdir)/libmisc -I$(top_srcdir)/lib
+DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
+
+libmisc_a_SOURCES = addgrps.c age.c basename.c chkname.c chkshell.c \
+ chowndir.c chowntty.c console.c copydir.c entry.c env.c failure.c \
+ fields.c getdate.y hushed.c isexpired.c limits.c list.c log.c \
+ login_access.c login_desrpc.c login_krb.c loginprompt.c mail.c motd.c \
+ myname.c obscure.c pam_pass.c pwd2spwd.c pwdcheck.c pwd_init.c rlogin.c \
+ salt.c setugid.c setup.c setupenv.c shell.c strtoday.c suauth.c sub.c \
+ sulog.c ttytype.c tz.c ulimit.c utmp.c valid.c xmalloc.c
+
diff --git a/current/libmisc/Makefile.in b/current/libmisc/Makefile.in
new file mode 100644
index 00000000..760788b5
--- /dev/null
+++ b/current/libmisc/Makefile.in
@@ -0,0 +1,435 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+noinst_HEADERS = chkname.h failure.h getdate.h
+
+noinst_LIBRARIES = libmisc.a
+
+libdir = $(prefix)/lib
+localedir = $(datadir)/locale
+INCLUDES = -I$(top_srcdir)/libmisc -I$(top_srcdir)/lib
+DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
+
+libmisc_a_SOURCES = addgrps.c age.c basename.c chkname.c chkshell.c chowndir.c chowntty.c console.c copydir.c entry.c env.c failure.c fields.c getdate.y hushed.c isexpired.c limits.c list.c log.c login_access.c login_desrpc.c login_krb.c loginprompt.c mail.c motd.c myname.c obscure.c pam_pass.c pwd2spwd.c pwdcheck.c pwd_init.c rlogin.c salt.c setugid.c setup.c setupenv.c shell.c strtoday.c suauth.c sub.c sulog.c ttytype.c tz.c ulimit.c utmp.c valid.c xmalloc.c
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libmisc_a_LIBADD =
+libmisc_a_OBJECTS = addgrps.o age.o basename.o chkname.o chkshell.o \
+chowndir.o chowntty.o console.o copydir.o entry.o env.o failure.o \
+fields.o getdate.o hushed.o isexpired.o limits.o list.o log.o \
+login_access.o login_desrpc.o login_krb.o loginprompt.o mail.o motd.o \
+myname.o obscure.o pam_pass.o pwd2spwd.o pwdcheck.o pwd_init.o rlogin.o \
+salt.o setugid.o setup.o setupenv.o shell.o strtoday.o suauth.o sub.o \
+sulog.o ttytype.o tz.o ulimit.o utmp.o valid.o xmalloc.o
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in getdate.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libmisc_a_SOURCES)
+OBJECTS = $(libmisc_a_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s .y
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps libmisc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmisc.a: $(libmisc_a_OBJECTS) $(libmisc_a_DEPENDENCIES)
+ -rm -f libmisc.a
+ $(AR) cru libmisc.a $(libmisc_a_OBJECTS) $(libmisc_a_LIBADD)
+ $(RANLIB) libmisc.a
+.y.c:
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+getdate.h: getdate.c
+
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = libmisc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+addgrps.o: addgrps.c ../config.h ../lib/prototypes.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/rcsid.h
+age.o: age.c ../config.h ../lib/prototypes.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/rcsid.h
+basename.o: basename.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/prototypes.h
+chkname.o: chkname.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h chkname.h
+chkshell.o: chkshell.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+chowndir.o: chowndir.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+chowntty.o: chowntty.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+console.o: console.c ../config.h ../lib/defines.h ../lib/gshadow_.h \
+ ../lib/getdef.h ../lib/rcsid.h
+copydir.o: copydir.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+entry.o: entry.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+env.o: env.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+failure.o: failure.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/faillog.h ../lib/getdef.h failure.h
+fields.o: fields.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+getdate.o: getdate.c ../config.h getdate.h ../lib/defines.h \
+ ../lib/gshadow_.h
+hushed.o: hushed.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/prototypes.h ../lib/getdef.h
+isexpired.o: isexpired.c ../config.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/rcsid.h
+limits.o: limits.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+list.o: list.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+login_access.o: login_access.c ../config.h ../lib/rcsid.h \
+ ../lib/prototypes.h ../lib/defines.h ../lib/gshadow_.h
+login_desrpc.o: login_desrpc.c ../config.h
+login_krb.o: login_krb.c ../config.h
+loginprompt.o: loginprompt.c ../config.h ../lib/rcsid.h \
+ ../lib/prototypes.h ../lib/defines.h ../lib/gshadow_.h \
+ ../lib/getdef.h
+log.o: log.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h
+mail.o: mail.c ../config.h ../lib/prototypes.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/getdef.h ../lib/rcsid.h
+motd.o: motd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+myname.o: myname.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/prototypes.h
+obscure.o: obscure.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+pam_pass.o: pam_pass.c ../config.h
+pwd2spwd.o: pwd2spwd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+pwdcheck.o: pwdcheck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h
+pwd_init.o: pwd_init.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h
+rlogin.o: rlogin.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+salt.o: salt.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+setugid.o: setugid.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+setupenv.o: setupenv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+setup.o: setup.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+shell.o: shell.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+strtoday.o: strtoday.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h getdate.h
+suauth.o: suauth.c ../config.h ../lib/prototypes.h ../lib/defines.h \
+ ../lib/gshadow_.h
+sub.o: sub.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+sulog.o: sulog.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+ttytype.o: ttytype.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+tz.o: tz.c ../config.h ../lib/rcsid.h ../lib/defines.h ../lib/gshadow_.h \
+ ../lib/getdef.h
+ulimit.o: ulimit.c ../config.h ../lib/rcsid.h
+utmp.o: utmp.c ../config.h ../lib/defines.h ../lib/gshadow_.h \
+ ../lib/rcsid.h
+valid.o: valid.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+xmalloc.o: xmalloc.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h
+
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -test -z "getdatehgetdatec" || rm -f getdateh getdatec
+mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/libmisc/addgrps.c b/current/libmisc/addgrps.c
new file mode 100644
index 00000000..589d295f
--- /dev/null
+++ b/current/libmisc/addgrps.c
@@ -0,0 +1,89 @@
+#include <config.h>
+
+#ifdef HAVE_SETGROUPS
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include <stdio.h>
+#include <grp.h>
+#include <errno.h>
+
+#include "rcsid.h"
+RCSID("$Id: addgrps.c,v 1.4 1998/12/28 20:34:41 marekm Exp $")
+
+#define SEP ",:"
+
+/*
+ * Add groups with names from LIST (separated by commas or colons)
+ * to the supplementary group set. Silently ignore groups which are
+ * already there. Warning: uses strtok().
+ */
+
+int
+add_groups(const char *list)
+{
+ GETGROUPS_T *grouplist, *tmp;
+ int i, ngroups, added;
+ struct group *grp;
+ char *token;
+ char buf[1024];
+
+ if (strlen(list) >= sizeof(buf)) {
+ errno = EINVAL;
+ return -1;
+ }
+ strcpy(buf, list);
+
+ i = 16;
+ for (;;) {
+ grouplist = malloc(i * sizeof(GETGROUPS_T));
+ if (!grouplist)
+ return -1;
+ ngroups = getgroups(i, grouplist);
+ if (i > ngroups)
+ break;
+ /* not enough room, so try allocating a larger buffer */
+ free(grouplist);
+ i *= 2;
+ }
+ if (ngroups < 0) {
+ free(grouplist);
+ return -1;
+ }
+
+ added = 0;
+ for (token = strtok(buf, SEP); token; token = strtok(NULL, SEP)) {
+
+ grp = getgrnam(token);
+ if (!grp) {
+ fprintf(stderr, _("Warning: unknown group %s\n"), token);
+ continue;
+ }
+
+ for (i = 0; i < ngroups && grouplist[i] != grp->gr_gid; i++)
+ ;
+
+ if (i < ngroups)
+ continue;
+
+ if (ngroups >= NGROUPS_MAX) {
+ fprintf(stderr, _("Warning: too many groups\n"));
+ break;
+ }
+ tmp = realloc(grouplist, (ngroups + 1) * sizeof(GETGROUPS_T));
+ if (!tmp) {
+ free(grouplist);
+ return -1;
+ }
+ tmp[ngroups++] = grp->gr_gid;
+ grouplist = tmp;
+ added++;
+ }
+
+ if (added)
+ return setgroups(ngroups, grouplist);
+
+ return 0;
+}
+#endif
diff --git a/current/libmisc/age.c b/current/libmisc/age.c
new file mode 100644
index 00000000..7d3b355f
--- /dev/null
+++ b/current/libmisc/age.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include <grp.h>
+#ifdef HAVE_USERSEC_H
+#include <userpw.h>
+#include <usersec.h>
+#include <userconf.h>
+#endif
+
+#ifndef AGING
+#if defined(SHADOWPWD) || defined(HAVE_USERSEC_H)
+#define AGING 1
+#endif
+#else
+#if !defined(SHADOWPWD) && !defined(HAVE_USERSEC_H) && !defined(ATT_AGE)
+#undef AGING
+#endif
+#endif
+
+#if defined(SHADOWPWD) || defined(AGING) /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: age.c,v 1.6 1998/12/28 20:34:42 marekm Exp $")
+
+#ifndef PASSWD_PROGRAM
+#define PASSWD_PROGRAM "/bin/passwd"
+#endif
+
+/*
+ * expire - force password change if password expired
+ *
+ * expire() calls /bin/passwd to change the user's password
+ * if it has expired.
+ */
+
+#ifdef SHADOWPWD
+int
+expire(const struct passwd *pw, const struct spwd *sp)
+{
+#else
+int
+expire(const struct passwd *pw)
+{
+#endif
+ int status;
+ int child;
+ int pid;
+
+#ifdef SHADOWPWD
+ if (! sp)
+ sp = pwd_to_spwd (pw);
+#endif
+
+ /*
+ * See if the user's password has expired, and if so
+ * force them to change their password.
+ */
+
+#ifdef SHADOWPWD
+ switch (status = isexpired (pw, sp))
+#else
+ switch (status = isexpired (pw))
+#endif
+ {
+ case 0:
+ return 0;
+ case 1:
+ printf(_("Your password has expired."));
+ break;
+ case 2:
+ printf(_("Your password is inactive."));
+ break;
+ case 3:
+ printf(_("Your login has expired."));
+ break;
+ }
+
+ /*
+ * Setting the maximum valid period to less than the minimum
+ * valid period means that the minimum period will never
+ * occur while the password is valid, so the user can never
+ * change that password.
+ */
+
+#ifdef SHADOWPWD
+ if (status > 1 || sp->sp_max < sp->sp_min)
+#else
+ if (status > 1 || c64i (pw->pw_age[0]) < c64i (pw->pw_age[1]))
+#endif
+ {
+ puts(_(" Contact the system administrator.\n"));
+ exit(1);
+ }
+ puts(_(" Choose a new password.\n"));
+ fflush (stdout);
+
+ /*
+ * Close all the files so that unauthorized access won't
+ * occur. This needs to be done anyway because those files
+ * might become stale after "passwd" is executed.
+ */
+
+#ifdef SHADOWPWD
+ endspent ();
+#endif
+ endpwent ();
+#ifdef SHADOWGRP
+ endsgent ();
+#endif
+ endgrent ();
+
+ /*
+ * Execute the /bin/passwd command. The exit status will be
+ * examined to see what the result is. If there are any
+ * errors the routine will exit. This forces the user to
+ * change their password before being able to use the account.
+ */
+
+ if ((pid = fork ()) == 0) {
+ int err;
+
+ /*
+ * Set the UID to be that of the user. This causes
+ * passwd to work just like it would had they executed
+ * it from the command line while logged in.
+ */
+ if (setup_uid_gid(pw, 0))
+ _exit(126);
+
+ execl(PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *)0);
+ err = errno;
+ perror("Can't execute " PASSWD_PROGRAM);
+ _exit((err == ENOENT) ? 127 : 126);
+ } else if (pid == -1) {
+ perror("fork");
+ exit(1);
+ }
+ while ((child = wait (&status)) != pid && child != -1)
+ ;
+
+ if (child == pid && status == 0)
+ return 1;
+
+ exit (1);
+ /*NOTREACHED*/
+}
+
+/*
+ * agecheck - see if warning is needed for password expiration
+ *
+ * agecheck sees how many days until the user's password is going
+ * to expire and warns the user of the pending password expiration.
+ */
+
+#ifdef SHADOWPWD
+void
+agecheck(const struct passwd *pw, const struct spwd *sp)
+{
+#else
+void
+agecheck(const struct passwd *pw)
+{
+#endif
+ long now = time ((long *) 0) / SCALE;
+ long remain;
+
+#ifdef SHADOWPWD
+ if (! sp)
+ sp = pwd_to_spwd (pw);
+
+ /*
+ * The last, max, and warn fields must be supported or the
+ * warning period cannot be calculated.
+ */
+
+ if (sp->sp_lstchg == -1 || sp->sp_max == -1 || sp->sp_warn == -1)
+ return;
+#else
+ if (pw->pw_age[0] == '\0')
+ return;
+#endif
+
+#ifdef SHADOWPWD
+ if ((remain = (sp->sp_lstchg + sp->sp_max) - now) <= sp->sp_warn)
+#else
+ if ((remain = (a64l (pw->pw_age + 2) + c64i (pw->pw_age[0])) * 7
+ - now) <= getdef_num ("PASS_WARN_AGE", 7))
+#endif
+ {
+ remain /= DAY/SCALE;
+ if (remain > 1)
+ printf(_("Your password will expire in %ld days.\n"), remain);
+ else if (remain == 1)
+ printf(_("Your password will expire tomorrow.\n"));
+ else if (remain == 0)
+ printf(_("Your password will expire today.\n"));
+ }
+}
+#endif /*}*/
diff --git a/current/libmisc/basename.c b/current/libmisc/basename.c
new file mode 100644
index 00000000..caf3ccdd
--- /dev/null
+++ b/current/libmisc/basename.c
@@ -0,0 +1,22 @@
+/*
+ * basename.c - not worth copyrighting :-). Some versions of Linux libc
+ * already have basename(), other versions don't. To avoid confusion,
+ * we will not use the function from libc and use a different name here.
+ * --marekm
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: basename.c,v 1.2 1997/12/07 23:27:00 marekm Exp $")
+
+#include "defines.h"
+#include "prototypes.h"
+
+char *
+Basename(char *str)
+{
+ char *cp = strrchr(str, '/');
+
+ return cp ? cp+1 : str;
+}
diff --git a/current/libmisc/chkname.c b/current/libmisc/chkname.c
new file mode 100644
index 00000000..8e71d69a
--- /dev/null
+++ b/current/libmisc/chkname.c
@@ -0,0 +1,73 @@
+/*
+ * check_user_name(), check_group_name() - check the new user/group
+ * name for validity; return value: 1 - OK, 0 - bad name
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: chkname.c,v 1.4 1998/04/16 19:57:43 marekm Exp $")
+
+#include <ctype.h>
+#include "defines.h"
+#include "chkname.h"
+
+#if HAVE_UTMPX_H
+#include <utmpx.h>
+#else
+#include <utmp.h>
+#endif
+
+static int
+good_name(const char *name)
+{
+ /*
+ * User/group names must start with a letter, and may not
+ * contain colons, commas, newlines (used in passwd/group
+ * files...) or any non-printable characters.
+ */
+ if (!*name || !isalpha(*name))
+ return 0;
+
+ while (*name) {
+ if (*name == ':' || *name == ',' ||
+ *name == '\n' || !isprint(*name))
+ return 0;
+
+ name++;
+ }
+
+ return 1;
+}
+
+int
+check_user_name(const char *name)
+{
+#if HAVE_UTMPX_H
+ struct utmpx ut;
+#else
+ struct utmp ut;
+#endif
+
+ /*
+ * User names are limited by whatever utmp can
+ * handle (usually max 8 characters).
+ */
+ if (strlen(name) > sizeof(ut.ut_user))
+ return 0;
+
+ return good_name(name);
+}
+
+int
+check_group_name(const char *name)
+{
+ /*
+ * Arbitrary limit for group names - max 16
+ * characters (same as on HP-UX 10).
+ */
+ if (strlen(name) > 16)
+ return 0;
+
+ return good_name(name);
+}
diff --git a/current/libmisc/chkname.h b/current/libmisc/chkname.h
new file mode 100644
index 00000000..b9e3ae02
--- /dev/null
+++ b/current/libmisc/chkname.h
@@ -0,0 +1,15 @@
+/* $Id: chkname.h,v 1.2 2000/08/26 18:27:17 marekm Exp $ */
+#ifndef _CHKNAME_H_
+#define _CHKNAME_H_
+
+/*
+ * check_user_name(), check_group_name() - check the new user/group
+ * name for validity; return value: 1 - OK, 0 - bad name
+ */
+
+#include "defines.h"
+
+extern int check_user_name(const char *);
+extern int check_group_name(const char *name);
+
+#endif
diff --git a/current/libmisc/chkshell.c b/current/libmisc/chkshell.c
new file mode 100644
index 00000000..d2a45d6f
--- /dev/null
+++ b/current/libmisc/chkshell.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: chkshell.c,v 1.1 1997/12/07 23:27:00 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#ifndef SHELLS_FILE
+#define SHELLS_FILE "/etc/shells"
+#endif
+
+/*
+ * check_shell - see if the user's login shell is listed in /etc/shells
+ *
+ * The /etc/shells file is read for valid names of login shells. If the
+ * /etc/shells file does not exist the user cannot set any shell unless
+ * they are root.
+ *
+ * If getusershell() is available (Linux, *BSD, possibly others), use it
+ * instead of re-implementing it.
+ */
+
+int
+check_shell(const char *sh)
+{
+ char *cp;
+ int found = 0;
+#ifndef HAVE_GETUSERSHELL
+ char buf[BUFSIZ];
+ FILE *fp;
+#endif
+
+#ifdef HAVE_GETUSERSHELL
+ setusershell();
+ while ((cp = getusershell())) {
+ if (*cp == '#')
+ continue;
+
+ if (strcmp(cp, sh) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ endusershell();
+#else
+ if ((fp = fopen (SHELLS_FILE, "r")) == (FILE *) 0)
+ return 0;
+
+ while (fgets (buf, sizeof(buf), fp)) {
+ if ((cp = strrchr(buf, '\n')))
+ *cp = '\0';
+
+ if (buf[0] == '#')
+ continue;
+
+ if (strcmp (buf, sh) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ fclose (fp);
+#endif
+ return found;
+}
+
diff --git a/current/libmisc/chowndir.c b/current/libmisc/chowndir.c
new file mode 100644
index 00000000..b89c5973
--- /dev/null
+++ b/current/libmisc/chowndir.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright 1992, 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: chowndir.c,v 1.6 2000/08/26 18:27:17 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+
+/*
+ * chown_tree - change ownership of files in a directory tree
+ *
+ * chown_dir() walks a directory tree and changes the ownership
+ * of all files owned by the provided user ID.
+ */
+
+int
+chown_tree(const char *root, uid_t old_uid, uid_t new_uid, gid_t old_gid, gid_t new_gid)
+{
+ char new_name[1024];
+ int rc = 0;
+ struct DIRECT *ent;
+ struct stat sb;
+ DIR *dir;
+
+ /*
+ * Make certain the directory exists. This routine is called
+ * directory by the invoker, or recursively.
+ */
+
+ if (access(root, F_OK) != 0)
+ return -1;
+
+ /*
+ * Open the directory and read each entry. Every entry is tested
+ * to see if it is a directory, and if so this routine is called
+ * recursively. If not, it is checked to see if it is owned by
+ * old user ID.
+ */
+
+ if (! (dir = opendir (root)))
+ return -1;
+
+ while ((ent = readdir (dir))) {
+
+ /*
+ * Skip the "." and ".." entries
+ */
+
+ if (strcmp (ent->d_name, ".") == 0 ||
+ strcmp (ent->d_name, "..") == 0)
+ continue;
+
+ /*
+ * Make the filename for both the source and the
+ * destination files.
+ */
+
+ if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name)
+ break;
+
+ snprintf(new_name, sizeof new_name, "%s/%s", root, ent->d_name);
+
+ /* Don't follow symbolic links! */
+ if (LSTAT(new_name, &sb) == -1)
+ continue;
+
+ if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) {
+
+ /*
+ * Do the entire subdirectory.
+ */
+
+ if ((rc = chown_tree (new_name, old_uid, new_uid,
+ old_gid, new_gid)))
+ break;
+ }
+#ifndef HAVE_LCHOWN
+ /* don't use chown (follows symbolic links!) */
+ if (S_ISLNK(sb.st_mode))
+ continue;
+#endif
+ if (sb.st_uid == old_uid)
+ LCHOWN(new_name, new_uid,
+ sb.st_gid == old_gid ? new_gid:sb.st_gid);
+ }
+ closedir (dir);
+
+ /*
+ * Now do the root of the tree
+ */
+
+ if (! stat (root, &sb)) {
+ if (sb.st_uid == old_uid)
+ LCHOWN(root, new_uid,
+ sb.st_gid == old_gid ? new_gid:sb.st_gid);
+ }
+ return rc;
+}
diff --git a/current/libmisc/chowntty.c b/current/libmisc/chowntty.c
new file mode 100644
index 00000000..f52b5a4a
--- /dev/null
+++ b/current/libmisc/chowntty.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: chowntty.c,v 1.7 1998/12/28 20:34:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <grp.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include "getdef.h"
+
+/*
+ * is_my_tty -- determine if "tty" is the same as TTY stdin is using
+ */
+
+static int
+is_my_tty(const char *tty)
+{
+ struct stat by_name, by_fd;
+
+ if (stat (tty, &by_name) || fstat (0, &by_fd))
+ return 0;
+
+ if (by_name.st_rdev != by_fd.st_rdev)
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * chown_tty() sets the login tty to be owned by the new user ID
+ * with TTYPERM modes
+ */
+
+void
+chown_tty(const char *tty, const struct passwd *info)
+{
+ char buf[200], full_tty[200];
+ char *group; /* TTY group name or number */
+ struct group *grent;
+ gid_t gid;
+
+ /*
+ * See if login.defs has some value configured for the port group
+ * ID. Otherwise, use the user's primary group ID.
+ */
+
+ if (! (group = getdef_str ("TTYGROUP")))
+ gid = info->pw_gid;
+ else if (group[0] >= '0' && group[0] <= '9')
+ gid = atoi (group);
+ else if ((grent = getgrnam (group)))
+ gid = grent->gr_gid;
+ else
+ gid = info->pw_gid;
+
+ /*
+ * Change the permissions on the TTY to be owned by the user with
+ * the group as determined above.
+ */
+
+ if (*tty != '/') {
+ snprintf(full_tty, sizeof full_tty, "/dev/%s", tty);
+ tty = full_tty;
+ }
+
+ if (! is_my_tty (tty)) {
+ SYSLOG((LOG_WARN, "unable to determine TTY name, got %s\n",
+ tty));
+ closelog();
+ exit (1);
+ }
+
+ if (chown(tty, info->pw_uid, gid) ||
+ chmod(tty, getdef_num("TTYPERM", 0600))) {
+ snprintf(buf, sizeof buf, _("Unable to change tty %s"), tty);
+ SYSLOG((LOG_WARN, "unable to change tty `%s' for user `%s'\n",
+ tty, info->pw_name));
+ closelog();
+ perror (buf);
+ exit(1);
+ }
+
+#ifdef __linux__
+ /*
+ * Please don't add code to chown /dev/vcs* to the user logging in -
+ * it's a potential security hole. I wouldn't like the previous user
+ * to hold the file descriptor open and watch my screen. We don't
+ * have the *BSD revoke() system call yet, and vhangup() only works
+ * for tty devices (which vcs* is not). --marekm
+ */
+#endif
+}
diff --git a/current/libmisc/console.c b/current/libmisc/console.c
new file mode 100644
index 00000000..75e69074
--- /dev/null
+++ b/current/libmisc/console.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1991, Julianne Frances Haugh and Chip Rosenthal
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include "defines.h"
+#include <stdio.h>
+#include "getdef.h"
+
+#include "rcsid.h"
+RCSID("$Id: console.c,v 1.5 1998/12/28 20:34:44 marekm Exp $")
+
+/*
+ * This is now rather generic function which decides if "tty" is listed
+ * under "cfgin" in config (directly or indirectly). Fallback to default if
+ * something is bad.
+ */
+int
+is_listed(const char *cfgin, const char *tty, int def)
+{
+ FILE *fp;
+ char buf[200], *cons, *s;
+
+ /*
+ * If the CONSOLE configuration definition isn't given,
+ * fallback to default.
+ */
+
+ if ((cons = getdef_str(cfgin)) == NULL)
+ return def;
+
+ /*
+ * If this isn't a filename, then it is a ":" delimited list of
+ * console devices upon which root logins are allowed.
+ */
+
+ if (*cons != '/') {
+ cons = strcpy(buf, cons);
+ while ((s = strtok(cons, ":")) != NULL) {
+ if (strcmp(s, tty) == 0)
+ return 1;
+
+ cons = NULL;
+ }
+ return 0;
+ }
+
+ /*
+ * If we can't open the console list, then call everything a
+ * console - otherwise root will never be allowed to login.
+ */
+
+ if ((fp = fopen(cons, "r")) == NULL)
+ return def;
+
+ /*
+ * See if this tty is listed in the console file.
+ */
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ buf[strlen(buf) - 1] = '\0';
+ if (strcmp(buf, tty) == 0) {
+ (void) fclose(fp);
+ return 1;
+ }
+ }
+
+ /*
+ * This tty isn't a console.
+ */
+
+ (void) fclose(fp);
+ return 0;
+}
+
+/*
+ * console - return 1 if the "tty" is a console device, else 0.
+ *
+ * Note - we need to take extreme care here to avoid locking out root logins
+ * if something goes awry. That's why we do things like call everything a
+ * console if the consoles file can't be opened. Because of this, we must
+ * warn the user to protect against the remove of the consoles file since
+ * that would allow an unauthorized root login.
+ */
+
+int
+console(const char *tty)
+{
+ return is_listed("CONSOLE", tty, 1);
+}
diff --git a/current/libmisc/copydir.c b/current/libmisc/copydir.c
new file mode 100644
index 00000000..0f7fed2d
--- /dev/null
+++ b/current/libmisc/copydir.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: copydir.c,v 1.7 2000/08/26 18:27:17 marekm Exp $")
+
+
+#include <sys/stat.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "prototypes.h"
+#include "defines.h"
+
+static const char *src_orig;
+static const char *dst_orig;
+
+struct link_name {
+ dev_t ln_dev;
+ ino_t ln_ino;
+ int ln_count;
+ char *ln_name;
+ struct link_name *ln_next;
+};
+static struct link_name *links;
+
+/*
+ * remove_link - delete a link from the link list
+ */
+
+static void
+remove_link(struct link_name *ln)
+{
+ struct link_name *lp;
+
+ if (links == ln) {
+ links = ln->ln_next;
+ free (ln->ln_name);
+ free (ln);
+ return;
+ }
+ for (lp = links;lp;lp = lp->ln_next)
+ if (lp->ln_next == ln)
+ break;
+
+ if (! lp)
+ return;
+
+ lp->ln_next = lp->ln_next->ln_next;
+ free (ln->ln_name);
+ free (ln);
+}
+
+/*
+ * check_link - see if a file is really a link
+ */
+
+static struct link_name *
+check_link(const char *name, const struct stat *sb)
+{
+ struct link_name *lp;
+ int src_len;
+ int dst_len;
+ int name_len;
+ int len;
+
+ for (lp = links;lp;lp = lp->ln_next)
+ if (lp->ln_dev == sb->st_dev && lp->ln_ino == sb->st_ino)
+ return lp;
+
+ if (sb->st_nlink == 1)
+ return 0;
+
+ lp = (struct link_name *) xmalloc (sizeof *lp);
+ src_len = strlen (src_orig);
+ dst_len = strlen (dst_orig);
+ name_len = strlen (name);
+ lp->ln_dev = sb->st_dev;
+ lp->ln_ino = sb->st_ino;
+ lp->ln_count = sb->st_nlink;
+ len = name_len - src_len + dst_len + 1;
+ lp->ln_name = xmalloc(len);
+ snprintf(lp->ln_name, len, "%s%s", dst_orig, name + src_len);
+ lp->ln_next = links;
+ links = lp;
+
+ return 0;
+}
+
+/*
+ * copy_tree - copy files in a directory tree
+ *
+ * copy_tree() walks a directory tree and copies ordinary files
+ * as it goes.
+ */
+
+int
+copy_tree(const char *src_root, const char *dst_root, uid_t uid, gid_t gid)
+{
+ char src_name[1024];
+ char dst_name[1024];
+ char buf[1024];
+ int ifd;
+ int ofd;
+ int err = 0;
+ int cnt;
+ int set_orig = 0;
+ struct DIRECT *ent;
+ struct stat sb;
+ struct link_name *lp;
+ DIR *dir;
+
+ /*
+ * Make certain both directories exist. This routine is called
+ * after the home directory is created, or recursively after the
+ * target is created. It assumes the target directory exists.
+ */
+
+ if (access(src_root, F_OK) != 0 || access(dst_root, F_OK) != 0)
+ return -1;
+
+ /*
+ * Open the source directory and read each entry. Every file
+ * entry in the directory is copied with the UID and GID set
+ * to the provided values. As an added security feature only
+ * regular files (and directories ...) are copied, and no file
+ * is made set-ID.
+ */
+
+ if (! (dir = opendir (src_root)))
+ return -1;
+
+ if (src_orig == 0) {
+ src_orig = src_root;
+ dst_orig = dst_root;
+ set_orig++;
+ }
+ while ((ent = readdir (dir))) {
+
+ /*
+ * Skip the "." and ".." entries
+ */
+
+ if (strcmp (ent->d_name, ".") == 0 ||
+ strcmp (ent->d_name, "..") == 0)
+ continue;
+
+ /*
+ * Make the filename for both the source and the
+ * destination files.
+ */
+
+ if (strlen (src_root) + strlen (ent->d_name) + 2 > sizeof src_name) {
+ err++;
+ break;
+ }
+ snprintf(src_name, sizeof src_name, "%s/%s", src_root, ent->d_name);
+
+ if (strlen (dst_root) + strlen (ent->d_name) + 2 > sizeof dst_name) {
+ err++;
+ break;
+ }
+ snprintf(dst_name, sizeof dst_name, "%s/%s", dst_root, ent->d_name);
+
+ if (LSTAT(src_name, &sb) == -1)
+ continue;
+
+ if (S_ISDIR(sb.st_mode)) {
+
+ /*
+ * Create a new target directory, make it owned by
+ * the user and then recursively copy that directory.
+ */
+
+ mkdir (dst_name, sb.st_mode & 0777);
+ chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid,
+ gid == (gid_t) -1 ? sb.st_gid:gid);
+
+ if (copy_tree (src_name, dst_name, uid, gid)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+#ifdef S_IFLNK
+ /*
+ * Copy any symbolic links
+ */
+
+ if (S_ISLNK(sb.st_mode)) {
+ char oldlink[1024];
+ char dummy[1024];
+ int len;
+
+ /*
+ * Get the name of the file which the link points
+ * to. If that name begins with the original
+ * source directory name, that part of the link
+ * name will be replaced with the original
+ * destinateion directory name.
+ */
+
+ if ((len = readlink(src_name, oldlink, sizeof(oldlink) - 1)) < 0) {
+ err++;
+ break;
+ }
+ oldlink[len] = '\0'; /* readlink() does not NUL-terminate */
+ if (!strncmp(oldlink, src_orig, strlen(src_orig))) {
+ snprintf(dummy, sizeof dummy, "%s%s",
+ dst_orig, oldlink + strlen(src_orig));
+ strcpy(oldlink, dummy);
+ }
+ if (symlink(oldlink, dst_name)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+#endif
+
+ /*
+ * See if this is a previously copied link
+ */
+
+ if ((lp = check_link (src_name, &sb))) {
+ if (link (lp->ln_name, dst_name)) {
+ err++;
+ break;
+ }
+ if (unlink (src_name)) {
+ err++;
+ break;
+ }
+ if (--lp->ln_count <= 0)
+ remove_link (lp);
+
+ continue;
+ }
+
+ /*
+ * Deal with FIFOs and special files. The user really
+ * shouldn't have any of these, but it seems like it
+ * would be nice to copy everything ...
+ */
+
+ if (!S_ISREG(sb.st_mode)) {
+ if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev) ||
+ chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid,
+ gid == (gid_t) -1 ? sb.st_gid:gid) ||
+ chmod (dst_name, sb.st_mode & 07777)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+
+ /*
+ * Create the new file and copy the contents. The new
+ * file will be owned by the provided UID and GID values.
+ */
+
+ if ((ifd = open (src_name, O_RDONLY)) < 0) {
+ err++;
+ break;
+ }
+ if ((ofd = open (dst_name, O_WRONLY|O_CREAT, 0)) < 0 ||
+ chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid,
+ gid == (gid_t) -1 ? sb.st_gid:gid) ||
+ chmod (dst_name, sb.st_mode & 07777)) {
+ close (ifd);
+ err++;
+ break;
+ }
+ while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
+ if (write (ofd, buf, cnt) != cnt) {
+ cnt = -1;
+ break;
+ }
+ }
+ close (ifd);
+ close (ofd);
+
+ if (cnt == -1) {
+ err++;
+ break;
+ }
+ }
+ closedir (dir);
+
+ if (set_orig) {
+ src_orig = 0;
+ dst_orig = 0;
+ }
+ return err ? -1:0;
+}
+
+/*
+ * remove_tree - remove files in a directory tree
+ *
+ * remove_tree() walks a directory tree and deletes all the files
+ * and directories.
+ */
+
+int
+remove_tree(const char *root)
+{
+ char new_name[1024];
+ int err = 0;
+ struct DIRECT *ent;
+ struct stat sb;
+ DIR *dir;
+
+ /*
+ * Make certain the directory exists.
+ */
+
+ if (access(root, F_OK) != 0)
+ return -1;
+
+ /*
+ * Open the source directory and read each entry. Every file
+ * entry in the directory is copied with the UID and GID set
+ * to the provided values. As an added security feature only
+ * regular files (and directories ...) are copied, and no file
+ * is made set-ID.
+ */
+
+ dir = opendir (root);
+
+ while ((ent = readdir (dir))) {
+
+ /*
+ * Skip the "." and ".." entries
+ */
+
+ if (strcmp (ent->d_name, ".") == 0 ||
+ strcmp (ent->d_name, "..") == 0)
+ continue;
+
+ /*
+ * Make the filename for the current entry.
+ */
+
+ if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) {
+ err++;
+ break;
+ }
+ snprintf(new_name, sizeof new_name, "%s/%s", root, ent->d_name);
+ if (LSTAT(new_name, &sb) == -1)
+ continue;
+
+ if (S_ISDIR(sb.st_mode)) {
+
+ /*
+ * Recursively delete this directory.
+ */
+
+ if (remove_tree (new_name)) {
+ err++;
+ break;
+ }
+ if (rmdir (new_name)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+ unlink (new_name);
+ }
+ closedir (dir);
+
+ return err ? -1:0;
+}
diff --git a/current/libmisc/entry.c b/current/libmisc/entry.c
new file mode 100644
index 00000000..746dfb0a
--- /dev/null
+++ b/current/libmisc/entry.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: entry.c,v 1.4 2000/08/26 18:27:17 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+
+extern struct passwd *fgetpwent ();
+
+void
+pw_entry(const char *name, struct passwd *pwent)
+{
+ struct passwd *passwd;
+#ifdef SHADOWPWD
+ struct spwd *spwd;
+#ifdef ATT_AGE
+ char *l64a ();
+ char *cp;
+#endif
+#endif
+
+ if (! (passwd = getpwnam (name))) {
+ pwent->pw_name = (char *) 0;
+ return;
+ } else {
+ pwent->pw_name = xstrdup (passwd->pw_name);
+ pwent->pw_uid = passwd->pw_uid;
+ pwent->pw_gid = passwd->pw_gid;
+#ifdef ATT_COMMENT
+ pwent->pw_comment = xstrdup (passwd->pw_comment);
+#endif
+ pwent->pw_gecos = xstrdup (passwd->pw_gecos);
+ pwent->pw_dir = xstrdup (passwd->pw_dir);
+ pwent->pw_shell = xstrdup (passwd->pw_shell);
+#if defined(SHADOWPWD) && !defined(AUTOSHADOW)
+ setspent ();
+ if ((spwd = getspnam (name))) {
+ pwent->pw_passwd = xstrdup (spwd->sp_pwdp);
+#ifdef ATT_AGE
+ pwent->pw_age = (char *) xmalloc (5);
+
+ if (spwd->sp_max > (63*7))
+ spwd->sp_max = (63*7);
+ if (spwd->sp_min > (63*7))
+ spwd->sp_min = (63*7);
+
+ pwent->pw_age[0] = i64c (spwd->sp_max / 7);
+ pwent->pw_age[1] = i64c (spwd->sp_min / 7);
+
+ cp = l64a (spwd->sp_lstchg / 7);
+ pwent->pw_age[2] = cp[0];
+ pwent->pw_age[3] = cp[1];
+
+ pwent->pw_age[4] = '\0';
+#endif
+ endspent ();
+ return;
+ }
+ endspent ();
+#endif
+ pwent->pw_passwd = xstrdup (passwd->pw_passwd);
+#ifdef ATT_AGE
+ pwent->pw_age = xstrdup (passwd->pw_age);
+#endif
+ }
+}
diff --git a/current/libmisc/env.c b/current/libmisc/env.c
new file mode 100644
index 00000000..8d7b2a11
--- /dev/null
+++ b/current/libmisc/env.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright 1989 - 1992, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: env.c,v 1.9 1999/03/07 19:14:38 marekm Exp $")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "prototypes.h"
+#include "defines.h"
+
+/*
+ * NEWENVP_STEP must be a power of two. This is the number
+ * of (char *) pointers to allocate at a time, to avoid using
+ * realloc() too often.
+ */
+#define NEWENVP_STEP 16
+
+size_t newenvc = 0;
+char **newenvp = NULL;
+extern char **environ;
+
+static const char *forbid[] = {
+ "_RLD_=",
+ "BASH_ENV=", /* GNU creeping featurism strikes again... */
+ "ENV=",
+ "HOME=",
+ "IFS=",
+ "KRB_CONF=",
+ "LD_", /* anything with the LD_ prefix */
+ "LIBPATH=",
+ "MAIL=",
+ "NLSPATH=",
+ "PATH=",
+ "SHELL=",
+ "SHLIB_PATH=",
+ (char *) 0
+};
+
+/* these are allowed, but with no slashes inside
+ (to work around security problems in GNU gettext) */
+static const char *noslash[] = {
+ "LANG=",
+ "LANGUAGE=",
+ "LC_", /* anything with the LC_ prefix */
+ (char *) 0
+};
+
+/*
+ * initenv() must be called once before using addenv().
+ */
+void
+initenv(void)
+{
+ newenvp = (char **)xmalloc(NEWENVP_STEP * sizeof(char *));
+ *newenvp = NULL;
+}
+
+
+void
+addenv(const char *string, const char *value)
+{
+ char *cp, *newstring;
+ size_t i;
+ size_t n;
+
+ if (value) {
+ newstring = xmalloc(strlen(string) + strlen(value) + 2);
+ sprintf(newstring, "%s=%s", string, value);
+ } else {
+ newstring = xstrdup(string);
+ }
+
+ /*
+ * Search for a '=' character within the string and if none is found
+ * just ignore the whole string.
+ */
+
+ cp = strchr(newstring, '=');
+ if (!cp) {
+ free(newstring);
+ return;
+ }
+
+ n = (size_t)(cp - newstring);
+
+ for (i = 0; i < newenvc; i++) {
+ if (strncmp(newstring, newenvp[i], n) == 0 &&
+ (newenvp[i][n] == '=' || newenvp[i][n] == '\0'))
+ break;
+ }
+
+ if (i < newenvc) {
+ free(newenvp[i]);
+ newenvp[i] = newstring;
+ return;
+ }
+
+ newenvp[newenvc++] = newstring;
+
+ /*
+ * Check whether newenvc is a multiple of NEWENVP_STEP.
+ * If so we have to resize the vector.
+ * the expression (newenvc & (NEWENVP_STEP - 1)) == 0
+ * is equal to (newenvc % NEWENVP_STEP) == 0
+ * as long as NEWENVP_STEP is a power of 2.
+ */
+
+ if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
+ char **__newenvp;
+ size_t newsize;
+
+ /*
+ * If the resize operation succeds we can
+ * happily go on, else print a message.
+ */
+
+ newsize = (newenvc + NEWENVP_STEP) * sizeof(char *);
+ __newenvp = (char **)realloc(newenvp, newsize);
+
+ if (__newenvp) {
+ /*
+ * If this is our current environment, update
+ * environ so that it doesn't point to some
+ * free memory area (realloc() could move it).
+ */
+ if (environ == newenvp)
+ environ = __newenvp;
+ newenvp = __newenvp;
+ } else {
+ fprintf(stderr, _("Environment overflow\n"));
+ free(newenvp[--newenvc]);
+ }
+ }
+
+ /*
+ * The last entry of newenvp must be NULL
+ */
+
+ newenvp[newenvc] = NULL;
+}
+
+
+/*
+ * set_env - copy command line arguments into the environment
+ */
+void
+set_env(int argc, char * const *argv)
+{
+ int noname = 1;
+ char variable[1024];
+ char *cp;
+
+ for ( ; argc > 0; argc--, argv++) {
+ if (strlen(*argv) >= sizeof variable)
+ continue; /* ignore long entries */
+
+ if (! (cp = strchr (*argv, '='))) {
+ snprintf(variable, sizeof variable, "L%d", noname++);
+ addenv(variable, *argv);
+ } else {
+ const char **p;
+
+ for (p = forbid; *p; p++)
+ if (strncmp(*argv, *p, strlen(*p)) == 0)
+ break;
+
+ if (*p) {
+ strncpy(variable, *argv, cp - *argv);
+ variable[cp - *argv] = '\0';
+ printf(_("You may not change $%s\n"), variable);
+ continue;
+ }
+
+ addenv(*argv, NULL);
+ }
+ }
+}
+
+/*
+ * sanitize_env - remove some nasty environment variables
+ * If you fall into a total paranoia, you should call this
+ * function for any root-setuid program or anything the user
+ * might change the environment with. 99% useless as almost
+ * all modern Unixes will handle setuid executables properly,
+ * but... I feel better with that silly precaution. -j.
+ */
+
+void
+sanitize_env(void)
+{
+ char **envp = environ;
+ const char **bad;
+ char **cur;
+ char **move;
+
+ for (cur = envp; *cur; cur++) {
+ for (bad = forbid; *bad; bad++) {
+ if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
+ for (move = cur; *move; move++)
+ *move = *(move + 1);
+ cur--;
+ break;
+ }
+ }
+ }
+
+ for (cur = envp; *cur; cur++) {
+ for (bad = noslash; *bad; bad++) {
+ if (strncmp(*cur, *bad, strlen(*bad)) != 0)
+ continue;
+ if (!strchr(*cur, '/'))
+ continue; /* OK */
+ for (move = cur; *move; move++)
+ *move = *(move + 1);
+ cur--;
+ break;
+ }
+ }
+}
+
diff --git a/current/libmisc/failure.c b/current/libmisc/failure.c
new file mode 100644
index 00000000..6f62ef1f
--- /dev/null
+++ b/current/libmisc/failure.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: failure.c,v 1.6 1998/12/28 20:34:46 marekm Exp $")
+
+#include <fcntl.h>
+#include <stdio.h>
+#include "defines.h"
+#include "faillog.h"
+#include "getdef.h"
+#include "failure.h"
+
+#include <utmp.h>
+
+#define YEAR (365L*DAY)
+
+/*
+ * failure - make failure entry
+ *
+ * failure() creates a new (struct faillog) entry or updates an
+ * existing one with the current failed login information.
+ */
+
+void
+failure(uid_t uid, const char *tty, struct faillog *fl)
+{
+ int fd;
+
+ /*
+ * Don't do anything if failure logging isn't set up.
+ */
+
+ if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0)
+ return;
+
+ /*
+ * The file is indexed by uid value meaning that shared UID's
+ * share failure log records. That's OK since they really
+ * share just about everything else ...
+ */
+
+ lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
+ if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl)
+ memzero(fl, sizeof *fl);
+
+ /*
+ * Update the record. We increment the failure count to log the
+ * latest failure. The only concern here is overflow, and we'll
+ * check for that. The line name and time of day are both
+ * updated as well.
+ */
+
+ if (fl->fail_cnt + 1 > 0)
+ fl->fail_cnt++;
+
+ strncpy(fl->fail_line, tty, sizeof fl->fail_line);
+ time(&fl->fail_time);
+
+ /*
+ * Seek back to the correct position in the file and write the
+ * record out. Ideally we should lock the file in case the same
+ * account is being logged simultaneously. But the risk doesn't
+ * seem that great.
+ */
+
+ lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
+ write(fd, (char *) fl, sizeof *fl);
+ close(fd);
+}
+
+static int
+too_many_failures(const struct faillog *fl)
+{
+ time_t now;
+
+ if (fl->fail_max == 0 || fl->fail_cnt < fl->fail_max)
+ return 0;
+
+ if (fl->fail_locktime == 0)
+ return 1; /* locked until reset manually */
+
+ time(&now);
+ if (fl->fail_time + fl->fail_locktime > now)
+ return 0; /* enough time since last failure */
+
+ return 1;
+}
+
+/*
+ * failcheck - check for failures > allowable
+ *
+ * failcheck() is called AFTER the password has been validated. If the
+ * account has been "attacked" with too many login failures, failcheck()
+ * returns FALSE to indicate that the login should be denied even though
+ * the password is valid.
+ */
+
+int
+failcheck(uid_t uid, struct faillog *fl, int failed)
+{
+ int fd;
+ struct faillog fail;
+
+ /*
+ * Suppress the check if the log file isn't there.
+ */
+
+ if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0)
+ return 1;
+
+ /*
+ * Get the record from the file and determine if the user has
+ * exceeded the failure limit. If "max" is zero, any number
+ * of failures are permitted. Only when "max" is non-zero and
+ * "cnt" is greater than or equal to "max" is the account
+ * considered to be locked.
+ *
+ * If read fails, there is no record for this user yet (the
+ * file is initially zero length and extended by writes), so
+ * no need to reset the count.
+ */
+
+ lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
+ if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl) {
+ close(fd);
+ return 1;
+ }
+
+ if (too_many_failures(fl)) {
+ close(fd);
+ return 0;
+ }
+
+ /*
+ * The record is updated if this is not a failure. The count will
+ * be reset to zero, but the rest of the information will be left
+ * in the record in case someone wants to see where the failed
+ * login originated.
+ */
+
+ if (!failed) {
+ fail = *fl;
+ fail.fail_cnt = 0;
+
+ lseek (fd, (off_t) sizeof fail * uid, SEEK_SET);
+ write (fd, (char *) &fail, sizeof fail);
+ }
+ close (fd);
+ return 1;
+}
+
+/*
+ * failprint - print line of failure information
+ *
+ * failprint takes a (struct faillog) entry and formats it into a
+ * message which is displayed at login time.
+ */
+
+void
+failprint(const struct faillog *fail)
+{
+ struct tm *tp;
+#if HAVE_STRFTIME
+ char lasttimeb[256];
+ char *lasttime = lasttimeb;
+ const char *fmt;
+#else
+ char *lasttime;
+#endif
+ time_t NOW;
+
+ if (fail->fail_cnt == 0)
+ return;
+
+ tp = localtime (&(fail->fail_time));
+ time(&NOW);
+
+#if HAVE_STRFTIME
+ /*
+ * Only print as much date and time info as it needed to
+ * know when the failure was.
+ */
+
+ if (NOW - fail->fail_time >= YEAR)
+ fmt = "%Y";
+ else if (NOW - fail->fail_time >= DAY)
+ fmt = "%A %T";
+ else
+ fmt = "%T";
+ strftime(lasttimeb, sizeof lasttimeb, fmt, tp);
+#else
+
+ /*
+ * Do the same thing, but don't use strftime since it
+ * probably doesn't exist on this system
+ */
+
+ lasttime = asctime (tp);
+ lasttime[24] = '\0';
+
+ if (NOW - fail->fail_time < YEAR)
+ lasttime[19] = '\0';
+ if (NOW - fail->fail_time < DAY)
+ lasttime = lasttime + 11;
+
+ if (*lasttime == ' ')
+ lasttime++;
+#endif
+ printf (_("%d %s since last login. Last was %s on %s.\n"),
+ fail->fail_cnt, fail->fail_cnt > 1 ? _("failures"):_("failure"),
+ lasttime, fail->fail_line);
+}
+
+/*
+ * failtmp - update the cummulative failure log
+ *
+ * failtmp updates the (struct utmp) formatted failure log which
+ * maintains a record of all login failures.
+ */
+
+void
+failtmp(const struct utmp *failent)
+{
+ char *ftmp;
+ int fd;
+
+ /*
+ * Get the name of the failure file. If no file has been defined
+ * in login.defs, don't do this.
+ */
+
+ if (!(ftmp = getdef_str("FTMP_FILE")))
+ return;
+
+ /*
+ * Open the file for append. It must already exist for this
+ * feature to be used.
+ */
+
+ if ((fd = open(ftmp, O_WRONLY|O_APPEND)) == -1)
+ return;
+
+ /*
+ * Output the new failure record and close the log file.
+ */
+
+ write(fd, (const char *) failent, sizeof *failent);
+ close(fd);
+}
diff --git a/current/libmisc/failure.h b/current/libmisc/failure.h
new file mode 100644
index 00000000..1795b50d
--- /dev/null
+++ b/current/libmisc/failure.h
@@ -0,0 +1,44 @@
+/* $Id: failure.h,v 1.2 2000/08/26 18:27:17 marekm Exp $ */
+#ifndef _FAILURE_H_
+#define _FAILURE_H_
+
+#include "defines.h"
+#include "faillog.h"
+#include <utmp.h>
+
+/*
+ * failure - make failure entry
+ *
+ * failure() creates a new (struct faillog) entry or updates an
+ * existing one with the current failed login information.
+ */
+extern void failure(uid_t, const char *, struct faillog *);
+
+/*
+ * failcheck - check for failures > allowable
+ *
+ * failcheck() is called AFTER the password has been validated. If the
+ * account has been "attacked" with too many login failures, failcheck()
+ * returns FALSE to indicate that the login should be denied even though
+ * the password is valid.
+ */
+extern int failcheck(uid_t, struct faillog *, int);
+
+/*
+ * failprint - print line of failure information
+ *
+ * failprint takes a (struct faillog) entry and formats it into a
+ * message which is displayed at login time.
+ */
+extern void failprint(const struct faillog *);
+
+/*
+ * failtmp - update the cummulative failure log
+ *
+ * failtmp updates the (struct utmp) formatted failure log which
+ * maintains a record of all login failures.
+ */
+extern void failtmp(const struct utmp *);
+
+#endif
+
diff --git a/current/libmisc/fields.c b/current/libmisc/fields.c
new file mode 100644
index 00000000..a645ec59
--- /dev/null
+++ b/current/libmisc/fields.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1990, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: fields.c,v 1.5 1997/12/07 23:27:04 marekm Exp $")
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include "prototypes.h"
+
+/*
+ * valid_field - insure that a field contains all legal characters
+ *
+ * The supplied field is scanned for non-printing and other illegal
+ * characters. If any illegal characters are found, valid_field
+ * returns -1. Zero is returned for success.
+ */
+
+int
+valid_field(const char *field, const char *illegal)
+{
+ const char *cp;
+
+ for (cp = field; *cp && isprint(*cp & 0x7F) && !strchr(illegal, *cp); cp++)
+ ;
+
+ if (*cp)
+ return -1;
+ else
+ return 0;
+}
+
+/*
+ * change_field - change a single field if a new value is given.
+ *
+ * prompt the user with the name of the field being changed and the
+ * current value.
+ */
+
+void
+change_field(char *buf, size_t maxsize, const char *prompt)
+{
+ char newf[200];
+ char *cp;
+
+ if (maxsize > sizeof(newf))
+ maxsize = sizeof(newf);
+
+ printf ("\t%s [%s]: ", prompt, buf);
+ if (fgets(newf, maxsize, stdin) != newf)
+ return;
+
+ if (!(cp = strchr(newf, '\n')))
+ return;
+ *cp = '\0';
+
+ if (newf[0]) {
+ /*
+ * Remove leading and trailing whitespace. This also
+ * makes it possible to change the field to empty, by
+ * entering a space. --marekm
+ */
+
+ while (--cp >= newf && isspace(*cp))
+ ;
+ *++cp = '\0';
+
+ cp = newf;
+ while (*cp && isspace(*cp))
+ cp++;
+
+ strncpy(buf, cp, maxsize - 1);
+ buf[maxsize - 1] = '\0';
+ }
+}
diff --git a/current/libmisc/getdate.c b/current/libmisc/getdate.c
new file mode 100644
index 00000000..559add3a
--- /dev/null
+++ b/current/libmisc/getdate.c
@@ -0,0 +1,2006 @@
+
+/* A Bison parser, made from getdate.y
+ by GNU Bison version 1.25
+ */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define tAGO 258
+#define tDAY 259
+#define tDAY_UNIT 260
+#define tDAYZONE 261
+#define tDST 262
+#define tHOUR_UNIT 263
+#define tID 264
+#define tMERIDIAN 265
+#define tMINUTE_UNIT 266
+#define tMONTH 267
+#define tMONTH_UNIT 268
+#define tSEC_UNIT 269
+#define tSNUMBER 270
+#define tUNUMBER 271
+#define tYEAR_UNIT 272
+#define tZONE 273
+
+#line 1 "getdate.y"
+
+/*
+** Originally written by Steven M. Bellovin <smb@research.att.com> while
+** at the University of North Carolina at Chapel Hill. Later tweaked by
+** a couple of people on Usenet. Completely overhauled by Rich $alz
+** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
+**
+** This grammar has 13 shift/reduce conflicts.
+**
+** This code is in the public domain and has no copyright.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+# ifdef FORCE_ALLOCA_H
+# include <alloca.h>
+# endif
+#endif
+
+/* Since the code of getdate.y is not included in the Emacs executable
+ itself, there is no need to #define static in this file. Even if
+ the code were included in the Emacs executable, it probably
+ wouldn't do any harm to #undef it here; this will only cause
+ problems if we try to write to a static variable, which I don't
+ think this code needs to do. */
+#ifdef emacs
+# undef static
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii(c)
+#endif
+
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
+#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+
+/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
+ only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
+ it's important to use the locale's definition of `digit' even when the
+ host does not conform to Posix. */
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+#include "getdate.h"
+
+#if defined (STDC_HEADERS) || defined (USG)
+# include <string.h>
+#endif
+
+/* Some old versions of bison generate parsers that use bcopy.
+ That loses on systems that don't provide the function, so we have
+ to redefine it here. */
+#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
+# define bcopy(from, to, len) memcpy ((to), (from), (len))
+#endif
+
+extern struct tm *gmtime ();
+extern struct tm *localtime ();
+extern time_t mktime ();
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in the same program. Note that these are only
+ the variables produced by yacc. If other parser generators (bison,
+ byacc, etc) produce additional global names that conflict at link time,
+ then those parser generators need to be fixed instead of adding those
+ names to this list. */
+
+#define yymaxdepth gd_maxdepth
+#define yyparse gd_parse
+#define yylex gd_lex
+#define yyerror gd_error
+#define yylval gd_lval
+#define yychar gd_char
+#define yydebug gd_debug
+#define yypact gd_pact
+#define yyr1 gd_r1
+#define yyr2 gd_r2
+#define yydef gd_def
+#define yychk gd_chk
+#define yypgo gd_pgo
+#define yyact gd_act
+#define yyexca gd_exca
+#define yyerrflag gd_errflag
+#define yynerrs gd_nerrs
+#define yyps gd_ps
+#define yypv gd_pv
+#define yys gd_s
+#define yy_yys gd_yys
+#define yystate gd_state
+#define yytmp gd_tmp
+#define yyv gd_v
+#define yy_yyv gd_yyv
+#define yyval gd_val
+#define yylloc gd_lloc
+#define yyreds gd_reds /* With YYDEBUG defined */
+#define yytoks gd_toks /* With YYDEBUG defined */
+#define yylhs gd_yylhs
+#define yylen gd_yylen
+#define yydefred gd_yydefred
+#define yydgoto gd_yydgoto
+#define yysindex gd_yysindex
+#define yyrindex gd_yyrindex
+#define yygindex gd_yygindex
+#define yytable gd_yytable
+#define yycheck gd_yycheck
+
+static int yylex ();
+static int yyerror ();
+
+#define EPOCH 1970
+#define HOUR(x) ((x) * 60)
+
+#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */
+
+/*
+** An entry in the lexical lookup table.
+*/
+typedef struct _TABLE {
+ const char *name;
+ int type;
+ int value;
+} TABLE;
+
+
+/*
+** Meridian: am, pm, or 24-hour style.
+*/
+typedef enum _MERIDIAN {
+ MERam, MERpm, MER24
+} MERIDIAN;
+
+
+/*
+** Global variables. We could get rid of most of these by using a good
+** union as the yacc stack. (This routine was originally written before
+** yacc had the %union construct.) Maybe someday; right now we only use
+** the %union very rarely.
+*/
+static const char *yyInput;
+static int yyDayOrdinal;
+static int yyDayNumber;
+static int yyHaveDate;
+static int yyHaveDay;
+static int yyHaveRel;
+static int yyHaveTime;
+static int yyHaveZone;
+static int yyTimezone;
+static int yyDay;
+static int yyHour;
+static int yyMinutes;
+static int yyMonth;
+static int yySeconds;
+static int yyYear;
+static MERIDIAN yyMeridian;
+static int yyRelDay;
+static int yyRelHour;
+static int yyRelMinutes;
+static int yyRelMonth;
+static int yyRelSeconds;
+static int yyRelYear;
+
+
+#line 175 "getdate.y"
+typedef union {
+ int Number;
+ enum _MERIDIAN Meridian;
+} YYSTYPE;
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 61
+#define YYFLAG -32768
+#define YYNTBASE 22
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 273 ? yytranslate[x] : 32)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 20, 2, 2, 21, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 19, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 1, 4, 6, 8, 10, 12, 14, 16, 19,
+ 24, 29, 36, 43, 45, 47, 50, 52, 55, 58,
+ 62, 68, 72, 76, 79, 84, 87, 91, 94, 96,
+ 99, 102, 104, 107, 110, 112, 115, 118, 120, 123,
+ 126, 128, 131, 134, 136, 139, 142, 144, 146, 147
+};
+
+static const short yyrhs[] = { -1,
+ 22, 23, 0, 24, 0, 25, 0, 27, 0, 26,
+ 0, 28, 0, 30, 0, 16, 10, 0, 16, 19,
+ 16, 31, 0, 16, 19, 16, 15, 0, 16, 19,
+ 16, 19, 16, 31, 0, 16, 19, 16, 19, 16,
+ 15, 0, 18, 0, 6, 0, 18, 7, 0, 4,
+ 0, 4, 20, 0, 16, 4, 0, 16, 21, 16,
+ 0, 16, 21, 16, 21, 16, 0, 16, 15, 15,
+ 0, 16, 12, 15, 0, 12, 16, 0, 12, 16,
+ 20, 16, 0, 16, 12, 0, 16, 12, 16, 0,
+ 29, 3, 0, 29, 0, 16, 17, 0, 15, 17,
+ 0, 17, 0, 16, 13, 0, 15, 13, 0, 13,
+ 0, 16, 5, 0, 15, 5, 0, 5, 0, 16,
+ 8, 0, 15, 8, 0, 8, 0, 16, 11, 0,
+ 15, 11, 0, 11, 0, 16, 14, 0, 15, 14,
+ 0, 14, 0, 16, 0, 0, 10, 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 191, 192, 195, 198, 201, 204, 207, 210, 213, 219,
+ 225, 234, 240, 252, 255, 258, 264, 268, 272, 278,
+ 282, 300, 306, 312, 316, 321, 325, 332, 340, 343,
+ 346, 349, 352, 355, 358, 361, 364, 367, 370, 373,
+ 376, 379, 382, 385, 388, 391, 394, 399, 432, 436
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = { "$","error","$undefined.","tAGO","tDAY",
+"tDAY_UNIT","tDAYZONE","tDST","tHOUR_UNIT","tID","tMERIDIAN","tMINUTE_UNIT",
+"tMONTH","tMONTH_UNIT","tSEC_UNIT","tSNUMBER","tUNUMBER","tYEAR_UNIT","tZONE",
+"':'","','","'/'","spec","item","time","zone","day","date","rel","relunit","number",
+"o_merid", NULL
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 22, 22, 23, 23, 23, 23, 23, 23, 24, 24,
+ 24, 24, 24, 25, 25, 25, 26, 26, 26, 27,
+ 27, 27, 27, 27, 27, 27, 27, 28, 28, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 30, 31, 31
+};
+
+static const short yyr2[] = { 0,
+ 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
+ 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
+ 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
+ 2, 1, 2, 2, 1, 2, 2, 1, 2, 2,
+ 1, 2, 2, 1, 2, 2, 1, 1, 0, 1
+};
+
+static const short yydefact[] = { 1,
+ 0, 17, 38, 15, 41, 44, 0, 35, 47, 0,
+ 48, 32, 14, 2, 3, 4, 6, 5, 7, 29,
+ 8, 18, 24, 37, 40, 43, 34, 46, 31, 19,
+ 36, 39, 9, 42, 26, 33, 45, 0, 30, 0,
+ 0, 16, 28, 0, 23, 27, 22, 49, 20, 25,
+ 50, 11, 0, 10, 0, 49, 21, 13, 12, 0,
+ 0
+};
+
+static const short yydefgoto[] = { 1,
+ 14, 15, 16, 17, 18, 19, 20, 21, 54
+};
+
+static const short yypact[] = {-32768,
+ 0, -19,-32768,-32768,-32768,-32768, -13,-32768,-32768, 30,
+ 15,-32768, 14,-32768,-32768,-32768,-32768,-32768,-32768, 19,
+-32768,-32768, 4,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, -6,-32768,-32768, 16,-32768, 17,
+ 23,-32768,-32768, 24,-32768,-32768,-32768, 27, 28,-32768,
+-32768,-32768, 29,-32768, 32, -8,-32768,-32768,-32768, 50,
+-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -5
+};
+
+
+#define YYLAST 51
+
+
+static const short yytable[] = { 60,
+ 22, 51, 23, 2, 3, 4, 58, 5, 45, 46,
+ 6, 7, 8, 9, 10, 11, 12, 13, 30, 31,
+ 42, 43, 32, 44, 33, 34, 35, 36, 37, 38,
+ 47, 39, 48, 40, 24, 41, 51, 25, 49, 50,
+ 26, 52, 27, 28, 56, 53, 29, 57, 55, 61,
+ 59
+};
+
+static const short yycheck[] = { 0,
+ 20, 10, 16, 4, 5, 6, 15, 8, 15, 16,
+ 11, 12, 13, 14, 15, 16, 17, 18, 4, 5,
+ 7, 3, 8, 20, 10, 11, 12, 13, 14, 15,
+ 15, 17, 16, 19, 5, 21, 10, 8, 16, 16,
+ 11, 15, 13, 14, 16, 19, 17, 16, 21, 0,
+ 56
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/share/bison.simple"
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (to, from, count)
+ char *to;
+ char *from;
+ int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (char *to, char *from, int count)
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 196 "/usr/share/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 3:
+#line 195 "getdate.y"
+{
+ yyHaveTime++;
+ ;
+ break;}
+case 4:
+#line 198 "getdate.y"
+{
+ yyHaveZone++;
+ ;
+ break;}
+case 5:
+#line 201 "getdate.y"
+{
+ yyHaveDate++;
+ ;
+ break;}
+case 6:
+#line 204 "getdate.y"
+{
+ yyHaveDay++;
+ ;
+ break;}
+case 7:
+#line 207 "getdate.y"
+{
+ yyHaveRel++;
+ ;
+ break;}
+case 9:
+#line 213 "getdate.y"
+{
+ yyHour = yyvsp[-1].Number;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = yyvsp[0].Meridian;
+ ;
+ break;}
+case 10:
+#line 219 "getdate.y"
+{
+ yyHour = yyvsp[-3].Number;
+ yyMinutes = yyvsp[-1].Number;
+ yySeconds = 0;
+ yyMeridian = yyvsp[0].Meridian;
+ ;
+ break;}
+case 11:
+#line 225 "getdate.y"
+{
+ yyHour = yyvsp[-3].Number;
+ yyMinutes = yyvsp[-1].Number;
+ yyMeridian = MER24;
+ yyHaveZone++;
+ yyTimezone = (yyvsp[0].Number < 0
+ ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60
+ : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60));
+ ;
+ break;}
+case 12:
+#line 234 "getdate.y"
+{
+ yyHour = yyvsp[-5].Number;
+ yyMinutes = yyvsp[-3].Number;
+ yySeconds = yyvsp[-1].Number;
+ yyMeridian = yyvsp[0].Meridian;
+ ;
+ break;}
+case 13:
+#line 240 "getdate.y"
+{
+ yyHour = yyvsp[-5].Number;
+ yyMinutes = yyvsp[-3].Number;
+ yySeconds = yyvsp[-1].Number;
+ yyMeridian = MER24;
+ yyHaveZone++;
+ yyTimezone = (yyvsp[0].Number < 0
+ ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60
+ : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60));
+ ;
+ break;}
+case 14:
+#line 252 "getdate.y"
+{
+ yyTimezone = yyvsp[0].Number;
+ ;
+ break;}
+case 15:
+#line 255 "getdate.y"
+{
+ yyTimezone = yyvsp[0].Number - 60;
+ ;
+ break;}
+case 16:
+#line 259 "getdate.y"
+{
+ yyTimezone = yyvsp[-1].Number - 60;
+ ;
+ break;}
+case 17:
+#line 264 "getdate.y"
+{
+ yyDayOrdinal = 1;
+ yyDayNumber = yyvsp[0].Number;
+ ;
+ break;}
+case 18:
+#line 268 "getdate.y"
+{
+ yyDayOrdinal = 1;
+ yyDayNumber = yyvsp[-1].Number;
+ ;
+ break;}
+case 19:
+#line 272 "getdate.y"
+{
+ yyDayOrdinal = yyvsp[-1].Number;
+ yyDayNumber = yyvsp[0].Number;
+ ;
+ break;}
+case 20:
+#line 278 "getdate.y"
+{
+ yyMonth = yyvsp[-2].Number;
+ yyDay = yyvsp[0].Number;
+ ;
+ break;}
+case 21:
+#line 282 "getdate.y"
+{
+ /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
+ The goal in recognizing YYYY/MM/DD is solely to support legacy
+ machine-generated dates like those in an RCS log listing. If
+ you want portability, use the ISO 8601 format. */
+ if (yyvsp[-4].Number >= 1000)
+ {
+ yyYear = yyvsp[-4].Number;
+ yyMonth = yyvsp[-2].Number;
+ yyDay = yyvsp[0].Number;
+ }
+ else
+ {
+ yyMonth = yyvsp[-4].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+ ;
+ break;}
+case 22:
+#line 300 "getdate.y"
+{
+ /* ISO 8601 format. yyyy-mm-dd. */
+ yyYear = yyvsp[-2].Number;
+ yyMonth = -yyvsp[-1].Number;
+ yyDay = -yyvsp[0].Number;
+ ;
+ break;}
+case 23:
+#line 306 "getdate.y"
+{
+ /* e.g. 17-JUN-1992. */
+ yyDay = yyvsp[-2].Number;
+ yyMonth = yyvsp[-1].Number;
+ yyYear = -yyvsp[0].Number;
+ ;
+ break;}
+case 24:
+#line 312 "getdate.y"
+{
+ yyMonth = yyvsp[-1].Number;
+ yyDay = yyvsp[0].Number;
+ ;
+ break;}
+case 25:
+#line 316 "getdate.y"
+{
+ yyMonth = yyvsp[-3].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ ;
+ break;}
+case 26:
+#line 321 "getdate.y"
+{
+ yyMonth = yyvsp[0].Number;
+ yyDay = yyvsp[-1].Number;
+ ;
+ break;}
+case 27:
+#line 325 "getdate.y"
+{
+ yyMonth = yyvsp[-1].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ ;
+ break;}
+case 28:
+#line 332 "getdate.y"
+{
+ yyRelSeconds = -yyRelSeconds;
+ yyRelMinutes = -yyRelMinutes;
+ yyRelHour = -yyRelHour;
+ yyRelDay = -yyRelDay;
+ yyRelMonth = -yyRelMonth;
+ yyRelYear = -yyRelYear;
+ ;
+ break;}
+case 30:
+#line 343 "getdate.y"
+{
+ yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 31:
+#line 346 "getdate.y"
+{
+ yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 32:
+#line 349 "getdate.y"
+{
+ yyRelYear++;
+ ;
+ break;}
+case 33:
+#line 352 "getdate.y"
+{
+ yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 34:
+#line 355 "getdate.y"
+{
+ yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 35:
+#line 358 "getdate.y"
+{
+ yyRelMonth++;
+ ;
+ break;}
+case 36:
+#line 361 "getdate.y"
+{
+ yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 37:
+#line 364 "getdate.y"
+{
+ yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 38:
+#line 367 "getdate.y"
+{
+ yyRelDay++;
+ ;
+ break;}
+case 39:
+#line 370 "getdate.y"
+{
+ yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 40:
+#line 373 "getdate.y"
+{
+ yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 41:
+#line 376 "getdate.y"
+{
+ yyRelHour++;
+ ;
+ break;}
+case 42:
+#line 379 "getdate.y"
+{
+ yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 43:
+#line 382 "getdate.y"
+{
+ yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 44:
+#line 385 "getdate.y"
+{
+ yyRelMinutes++;
+ ;
+ break;}
+case 45:
+#line 388 "getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 46:
+#line 391 "getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
+ ;
+ break;}
+case 47:
+#line 394 "getdate.y"
+{
+ yyRelSeconds++;
+ ;
+ break;}
+case 48:
+#line 400 "getdate.y"
+{
+ if (yyHaveTime && yyHaveDate && !yyHaveRel)
+ yyYear = yyvsp[0].Number;
+ else
+ {
+ if (yyvsp[0].Number>10000)
+ {
+ yyHaveDate++;
+ yyDay= (yyvsp[0].Number)%100;
+ yyMonth= (yyvsp[0].Number/100)%100;
+ yyYear = yyvsp[0].Number/10000;
+ }
+ else
+ {
+ yyHaveTime++;
+ if (yyvsp[0].Number < 100)
+ {
+ yyHour = yyvsp[0].Number;
+ yyMinutes = 0;
+ }
+ else
+ {
+ yyHour = yyvsp[0].Number / 100;
+ yyMinutes = yyvsp[0].Number % 100;
+ }
+ yySeconds = 0;
+ yyMeridian = MER24;
+ }
+ }
+ ;
+ break;}
+case 49:
+#line 433 "getdate.y"
+{
+ yyval.Meridian = MER24;
+ ;
+ break;}
+case 50:
+#line 437 "getdate.y"
+{
+ yyval.Meridian = yyvsp[0].Meridian;
+ ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 498 "/usr/share/bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+ goto yyerrlab1;
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
+#line 442 "getdate.y"
+
+
+/* Month and day table. */
+static TABLE const MonthDayTable[] = {
+ { "january", tMONTH, 1 },
+ { "february", tMONTH, 2 },
+ { "march", tMONTH, 3 },
+ { "april", tMONTH, 4 },
+ { "may", tMONTH, 5 },
+ { "june", tMONTH, 6 },
+ { "july", tMONTH, 7 },
+ { "august", tMONTH, 8 },
+ { "september", tMONTH, 9 },
+ { "sept", tMONTH, 9 },
+ { "october", tMONTH, 10 },
+ { "november", tMONTH, 11 },
+ { "december", tMONTH, 12 },
+ { "sunday", tDAY, 0 },
+ { "monday", tDAY, 1 },
+ { "tuesday", tDAY, 2 },
+ { "tues", tDAY, 2 },
+ { "wednesday", tDAY, 3 },
+ { "wednes", tDAY, 3 },
+ { "thursday", tDAY, 4 },
+ { "thur", tDAY, 4 },
+ { "thurs", tDAY, 4 },
+ { "friday", tDAY, 5 },
+ { "saturday", tDAY, 6 },
+ { NULL }
+};
+
+/* Time units table. */
+static TABLE const UnitsTable[] = {
+ { "year", tYEAR_UNIT, 1 },
+ { "month", tMONTH_UNIT, 1 },
+ { "fortnight", tDAY_UNIT, 14 },
+ { "week", tDAY_UNIT, 7 },
+ { "day", tDAY_UNIT, 1 },
+ { "hour", tHOUR_UNIT, 1 },
+ { "minute", tMINUTE_UNIT, 1 },
+ { "min", tMINUTE_UNIT, 1 },
+ { "second", tSEC_UNIT, 1 },
+ { "sec", tSEC_UNIT, 1 },
+ { NULL }
+};
+
+/* Assorted relative-time words. */
+static TABLE const OtherTable[] = {
+ { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
+ { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
+ { "today", tMINUTE_UNIT, 0 },
+ { "now", tMINUTE_UNIT, 0 },
+ { "last", tUNUMBER, -1 },
+ { "this", tMINUTE_UNIT, 0 },
+ { "next", tUNUMBER, 2 },
+ { "first", tUNUMBER, 1 },
+/* { "second", tUNUMBER, 2 }, */
+ { "third", tUNUMBER, 3 },
+ { "fourth", tUNUMBER, 4 },
+ { "fifth", tUNUMBER, 5 },
+ { "sixth", tUNUMBER, 6 },
+ { "seventh", tUNUMBER, 7 },
+ { "eighth", tUNUMBER, 8 },
+ { "ninth", tUNUMBER, 9 },
+ { "tenth", tUNUMBER, 10 },
+ { "eleventh", tUNUMBER, 11 },
+ { "twelfth", tUNUMBER, 12 },
+ { "ago", tAGO, 1 },
+ { NULL }
+};
+
+/* The timezone table. */
+static TABLE const TimezoneTable[] = {
+ { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */
+ { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
+ { "utc", tZONE, HOUR ( 0) },
+ { "wet", tZONE, HOUR ( 0) }, /* Western European */
+ { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */
+ { "wat", tZONE, HOUR ( 1) }, /* West Africa */
+ { "at", tZONE, HOUR ( 2) }, /* Azores */
+#if 0
+ /* For completeness. BST is also British Summer, and GST is
+ * also Guam Standard. */
+ { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */
+ { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */
+#endif
+#if 0
+ { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */
+ { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */
+ { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */
+#endif
+ { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */
+ { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */
+ { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */
+ { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */
+ { "cst", tZONE, HOUR ( 6) }, /* Central Standard */
+ { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */
+ { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */
+ { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */
+ { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */
+ { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */
+ { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */
+ { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */
+ { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */
+ { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */
+ { "cat", tZONE, HOUR (10) }, /* Central Alaska */
+ { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */
+ { "nt", tZONE, HOUR (11) }, /* Nome */
+ { "idlw", tZONE, HOUR (12) }, /* International Date Line West */
+ { "cet", tZONE, -HOUR (1) }, /* Central European */
+ { "met", tZONE, -HOUR (1) }, /* Middle European */
+ { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */
+ { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
+ { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
+ { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */
+ { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */
+ { "fwt", tZONE, -HOUR (1) }, /* French Winter */
+ { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */
+ { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */
+ { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */
+#if 0
+ { "it", tZONE, -HOUR (3.5) },/* Iran */
+#endif
+ { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */
+ { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */
+#if 0
+ { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */
+#endif
+ { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */
+#if 0
+ /* For completeness. NST is also Newfoundland Standard, and SST is
+ * also Swedish Summer. */
+ { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */
+ { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */
+#endif /* 0 */
+ { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */
+ { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */
+#if 0
+ { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */
+#endif
+ { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */
+ { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */
+#if 0
+ { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */
+ { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */
+#endif
+ { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */
+ { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */
+ { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */
+ { "nzt", tZONE, -HOUR (12) }, /* New Zealand */
+ { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */
+ { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */
+ { "idle", tZONE, -HOUR (12) }, /* International Date Line East */
+ { NULL }
+};
+
+/* Military timezone table. */
+static TABLE const MilitaryTable[] = {
+ { "a", tZONE, HOUR ( 1) },
+ { "b", tZONE, HOUR ( 2) },
+ { "c", tZONE, HOUR ( 3) },
+ { "d", tZONE, HOUR ( 4) },
+ { "e", tZONE, HOUR ( 5) },
+ { "f", tZONE, HOUR ( 6) },
+ { "g", tZONE, HOUR ( 7) },
+ { "h", tZONE, HOUR ( 8) },
+ { "i", tZONE, HOUR ( 9) },
+ { "k", tZONE, HOUR ( 10) },
+ { "l", tZONE, HOUR ( 11) },
+ { "m", tZONE, HOUR ( 12) },
+ { "n", tZONE, HOUR (- 1) },
+ { "o", tZONE, HOUR (- 2) },
+ { "p", tZONE, HOUR (- 3) },
+ { "q", tZONE, HOUR (- 4) },
+ { "r", tZONE, HOUR (- 5) },
+ { "s", tZONE, HOUR (- 6) },
+ { "t", tZONE, HOUR (- 7) },
+ { "u", tZONE, HOUR (- 8) },
+ { "v", tZONE, HOUR (- 9) },
+ { "w", tZONE, HOUR (-10) },
+ { "x", tZONE, HOUR (-11) },
+ { "y", tZONE, HOUR (-12) },
+ { "z", tZONE, HOUR ( 0) },
+ { NULL }
+};
+
+
+
+
+/* ARGSUSED */
+static int
+yyerror (s)
+ char *s;
+{
+ return 0;
+}
+
+static int
+ToHour (Hours, Meridian)
+ int Hours;
+ MERIDIAN Meridian;
+{
+ switch (Meridian)
+ {
+ case MER24:
+ if (Hours < 0 || Hours > 23)
+ return -1;
+ return Hours;
+ case MERam:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return Hours;
+ case MERpm:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return Hours + 12;
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+}
+
+static int
+ToYear (Year)
+ int Year;
+{
+ if (Year < 0)
+ Year = -Year;
+
+ /* XPG4 suggests that years 00-68 map to 2000-2068, and
+ years 69-99 map to 1969-1999. */
+ if (Year < 69)
+ Year += 2000;
+ else if (Year < 100)
+ Year += 1900;
+
+ return Year;
+}
+
+static int
+LookupWord (buff)
+ char *buff;
+{
+ register char *p;
+ register char *q;
+ register const TABLE *tp;
+ int i;
+ int abbrev;
+
+ /* Make it lowercase. */
+ for (p = buff; *p; p++)
+ if (ISUPPER (*p))
+ *p = tolower (*p);
+
+ if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
+ {
+ yylval.Meridian = MERam;
+ return tMERIDIAN;
+ }
+ if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0)
+ {
+ yylval.Meridian = MERpm;
+ return tMERIDIAN;
+ }
+
+ /* See if we have an abbreviation for a month. */
+ if (strlen (buff) == 3)
+ abbrev = 1;
+ else if (strlen (buff) == 4 && buff[3] == '.')
+ {
+ abbrev = 1;
+ buff[3] = '\0';
+ }
+ else
+ abbrev = 0;
+
+ for (tp = MonthDayTable; tp->name; tp++)
+ {
+ if (abbrev)
+ {
+ if (strncmp (buff, tp->name, 3) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+ else if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ if (strcmp (buff, "dst") == 0)
+ return tDST;
+
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Strip off any plural and try the units table again. */
+ i = strlen (buff) - 1;
+ if (buff[i] == 's')
+ {
+ buff[i] = '\0';
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ buff[i] = 's'; /* Put back for "this" in OtherTable. */
+ }
+
+ for (tp = OtherTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Military timezones. */
+ if (buff[1] == '\0' && ISALPHA (*buff))
+ {
+ for (tp = MilitaryTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ /* Drop out any periods and try the timezone table again. */
+ for (i = 0, p = q = buff; *q; q++)
+ if (*q != '.')
+ *p++ = *q;
+ else
+ i++;
+ *p = '\0';
+ if (i)
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ return tID;
+}
+
+static int
+yylex ()
+{
+ register char c;
+ register char *p;
+ char buff[20];
+ int Count;
+ int sign;
+
+ for (;;)
+ {
+ while (ISSPACE (*yyInput))
+ yyInput++;
+
+ if (ISDIGIT (c = *yyInput) || c == '-' || c == '+')
+ {
+ if (c == '-' || c == '+')
+ {
+ sign = c == '-' ? -1 : 1;
+ if (!ISDIGIT (*++yyInput))
+ /* skip the '-' sign */
+ continue;
+ }
+ else
+ sign = 0;
+ for (yylval.Number = 0; ISDIGIT (c = *yyInput++);)
+ yylval.Number = 10 * yylval.Number + c - '0';
+ yyInput--;
+ if (sign < 0)
+ yylval.Number = -yylval.Number;
+ return sign ? tSNUMBER : tUNUMBER;
+ }
+ if (ISALPHA (c))
+ {
+ for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';)
+ if (p < &buff[sizeof buff - 1])
+ *p++ = c;
+ *p = '\0';
+ yyInput--;
+ return LookupWord (buff);
+ }
+ if (c != '(')
+ return *yyInput++;
+ Count = 0;
+ do
+ {
+ c = *yyInput++;
+ if (c == '\0')
+ return c;
+ if (c == '(')
+ Count++;
+ else if (c == ')')
+ Count--;
+ }
+ while (Count > 0);
+ }
+}
+
+#define TM_YEAR_ORIGIN 1900
+
+/* Yield A - B, measured in seconds. */
+static long
+difftm (a, b)
+ struct tm *a, *b;
+{
+ int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
+ int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
+ long days = (
+ /* difference in day of year */
+ a->tm_yday - b->tm_yday
+ /* + intervening leap days */
+ + ((ay >> 2) - (by >> 2))
+ - (ay / 100 - by / 100)
+ + ((ay / 100 >> 2) - (by / 100 >> 2))
+ /* + difference in years * 365 */
+ + (long) (ay - by) * 365
+ );
+ return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+
+time_t
+get_date (p, now)
+ const char *p;
+ const time_t *now;
+{
+ struct tm tm, tm0, *tmp;
+ time_t Start;
+
+ yyInput = p;
+ Start = now ? *now : time ((time_t *) NULL);
+ tmp = localtime (&Start);
+ yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
+ yyMonth = tmp->tm_mon + 1;
+ yyDay = tmp->tm_mday;
+ yyHour = tmp->tm_hour;
+ yyMinutes = tmp->tm_min;
+ yySeconds = tmp->tm_sec;
+ yyMeridian = MER24;
+ yyRelSeconds = 0;
+ yyRelMinutes = 0;
+ yyRelHour = 0;
+ yyRelDay = 0;
+ yyRelMonth = 0;
+ yyRelYear = 0;
+ yyHaveDate = 0;
+ yyHaveDay = 0;
+ yyHaveRel = 0;
+ yyHaveTime = 0;
+ yyHaveZone = 0;
+
+ if (yyparse ()
+ || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
+ return -1;
+
+ tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
+ tm.tm_mon = yyMonth - 1 + yyRelMonth;
+ tm.tm_mday = yyDay + yyRelDay;
+ if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay))
+ {
+ tm.tm_hour = ToHour (yyHour, yyMeridian);
+ if (tm.tm_hour < 0)
+ return -1;
+ tm.tm_min = yyMinutes;
+ tm.tm_sec = yySeconds;
+ }
+ else
+ {
+ tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ }
+ tm.tm_hour += yyRelHour;
+ tm.tm_min += yyRelMinutes;
+ tm.tm_sec += yyRelSeconds;
+ tm.tm_isdst = -1;
+ tm0 = tm;
+
+ Start = mktime (&tm);
+
+ if (Start == (time_t) -1)
+ {
+
+ /* Guard against falsely reporting errors near the time_t boundaries
+ when parsing times in other time zones. For example, if the min
+ time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
+ of UTC, then the min localtime value is 1970-01-01 08:00:00; if
+ we apply mktime to 1970-01-01 00:00:00 we will get an error, so
+ we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
+ zone by 24 hours to compensate. This algorithm assumes that
+ there is no DST transition within a day of the time_t boundaries. */
+ if (yyHaveZone)
+ {
+ tm = tm0;
+ if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
+ {
+ tm.tm_mday++;
+ yyTimezone -= 24 * 60;
+ }
+ else
+ {
+ tm.tm_mday--;
+ yyTimezone += 24 * 60;
+ }
+ Start = mktime (&tm);
+ }
+
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (yyHaveDay && !yyHaveDate)
+ {
+ tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
+ + 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
+ Start = mktime (&tm);
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (yyHaveZone)
+ {
+ long delta = yyTimezone * 60L + difftm (&tm, gmtime (&Start));
+ if ((Start + delta < Start) != (delta < 0))
+ return -1; /* time_t overflow */
+ Start += delta;
+ }
+
+ return Start;
+}
+
+#if defined (TEST)
+
+/* ARGSUSED */
+int
+main (ac, av)
+ int ac;
+ char *av[];
+{
+ char buff[MAX_BUFF_LEN + 1];
+ time_t d;
+
+ (void) printf ("Enter date, or blank line to exit.\n\t> ");
+ (void) fflush (stdout);
+
+ buff[MAX_BUFF_LEN] = 0;
+ while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
+ {
+ d = get_date (buff, (time_t *) NULL);
+ if (d == -1)
+ (void) printf ("Bad format - couldn't convert.\n");
+ else
+ (void) printf ("%s", ctime (&d));
+ (void) printf ("\t> ");
+ (void) fflush (stdout);
+ }
+ exit (0);
+ /* NOTREACHED */
+}
+#endif /* defined (TEST) */
diff --git a/current/libmisc/getdate.h b/current/libmisc/getdate.h
new file mode 100644
index 00000000..691a508f
--- /dev/null
+++ b/current/libmisc/getdate.h
@@ -0,0 +1,8 @@
+#ifndef _GETDATE_H_
+#define _GETDATE_H_
+
+#include <config.h>
+#include "defines.h"
+
+time_t get_date(const char *, const time_t *);
+#endif
diff --git a/current/libmisc/getdate.y b/current/libmisc/getdate.y
new file mode 100644
index 00000000..d33fa063
--- /dev/null
+++ b/current/libmisc/getdate.y
@@ -0,0 +1,1024 @@
+%{
+/*
+** Originally written by Steven M. Bellovin <smb@research.att.com> while
+** at the University of North Carolina at Chapel Hill. Later tweaked by
+** a couple of people on Usenet. Completely overhauled by Rich $alz
+** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
+**
+** This grammar has 13 shift/reduce conflicts.
+**
+** This code is in the public domain and has no copyright.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+# ifdef FORCE_ALLOCA_H
+# include <alloca.h>
+# endif
+#endif
+
+/* Since the code of getdate.y is not included in the Emacs executable
+ itself, there is no need to #define static in this file. Even if
+ the code were included in the Emacs executable, it probably
+ wouldn't do any harm to #undef it here; this will only cause
+ problems if we try to write to a static variable, which I don't
+ think this code needs to do. */
+#ifdef emacs
+# undef static
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii(c)
+#endif
+
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
+#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+
+/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
+ only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
+ it's important to use the locale's definition of `digit' even when the
+ host does not conform to Posix. */
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+#include "getdate.h"
+
+#if defined (STDC_HEADERS) || defined (USG)
+# include <string.h>
+#endif
+
+/* Some old versions of bison generate parsers that use bcopy.
+ That loses on systems that don't provide the function, so we have
+ to redefine it here. */
+#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
+# define bcopy(from, to, len) memcpy ((to), (from), (len))
+#endif
+
+extern struct tm *gmtime ();
+extern struct tm *localtime ();
+extern time_t mktime ();
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in the same program. Note that these are only
+ the variables produced by yacc. If other parser generators (bison,
+ byacc, etc) produce additional global names that conflict at link time,
+ then those parser generators need to be fixed instead of adding those
+ names to this list. */
+
+#define yymaxdepth gd_maxdepth
+#define yyparse gd_parse
+#define yylex gd_lex
+#define yyerror gd_error
+#define yylval gd_lval
+#define yychar gd_char
+#define yydebug gd_debug
+#define yypact gd_pact
+#define yyr1 gd_r1
+#define yyr2 gd_r2
+#define yydef gd_def
+#define yychk gd_chk
+#define yypgo gd_pgo
+#define yyact gd_act
+#define yyexca gd_exca
+#define yyerrflag gd_errflag
+#define yynerrs gd_nerrs
+#define yyps gd_ps
+#define yypv gd_pv
+#define yys gd_s
+#define yy_yys gd_yys
+#define yystate gd_state
+#define yytmp gd_tmp
+#define yyv gd_v
+#define yy_yyv gd_yyv
+#define yyval gd_val
+#define yylloc gd_lloc
+#define yyreds gd_reds /* With YYDEBUG defined */
+#define yytoks gd_toks /* With YYDEBUG defined */
+#define yylhs gd_yylhs
+#define yylen gd_yylen
+#define yydefred gd_yydefred
+#define yydgoto gd_yydgoto
+#define yysindex gd_yysindex
+#define yyrindex gd_yyrindex
+#define yygindex gd_yygindex
+#define yytable gd_yytable
+#define yycheck gd_yycheck
+
+static int yylex ();
+static int yyerror ();
+
+#define EPOCH 1970
+#define HOUR(x) ((x) * 60)
+
+#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */
+
+/*
+** An entry in the lexical lookup table.
+*/
+typedef struct _TABLE {
+ const char *name;
+ int type;
+ int value;
+} TABLE;
+
+
+/*
+** Meridian: am, pm, or 24-hour style.
+*/
+typedef enum _MERIDIAN {
+ MERam, MERpm, MER24
+} MERIDIAN;
+
+
+/*
+** Global variables. We could get rid of most of these by using a good
+** union as the yacc stack. (This routine was originally written before
+** yacc had the %union construct.) Maybe someday; right now we only use
+** the %union very rarely.
+*/
+static const char *yyInput;
+static int yyDayOrdinal;
+static int yyDayNumber;
+static int yyHaveDate;
+static int yyHaveDay;
+static int yyHaveRel;
+static int yyHaveTime;
+static int yyHaveZone;
+static int yyTimezone;
+static int yyDay;
+static int yyHour;
+static int yyMinutes;
+static int yyMonth;
+static int yySeconds;
+static int yyYear;
+static MERIDIAN yyMeridian;
+static int yyRelDay;
+static int yyRelHour;
+static int yyRelMinutes;
+static int yyRelMonth;
+static int yyRelSeconds;
+static int yyRelYear;
+
+%}
+
+%union {
+ int Number;
+ enum _MERIDIAN Meridian;
+}
+
+%token tAGO tDAY tDAY_UNIT tDAYZONE tDST tHOUR_UNIT tID
+%token tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
+%token tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
+
+%type <Number> tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tMINUTE_UNIT
+%type <Number> tMONTH tMONTH_UNIT
+%type <Number> tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
+%type <Meridian> tMERIDIAN o_merid
+
+%%
+
+spec : /* NULL */
+ | spec item
+ ;
+
+item : time {
+ yyHaveTime++;
+ }
+ | zone {
+ yyHaveZone++;
+ }
+ | date {
+ yyHaveDate++;
+ }
+ | day {
+ yyHaveDay++;
+ }
+ | rel {
+ yyHaveRel++;
+ }
+ | number
+ ;
+
+time : tUNUMBER tMERIDIAN {
+ yyHour = $1;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = $2;
+ }
+ | tUNUMBER ':' tUNUMBER o_merid {
+ yyHour = $1;
+ yyMinutes = $3;
+ yySeconds = 0;
+ yyMeridian = $4;
+ }
+ | tUNUMBER ':' tUNUMBER tSNUMBER {
+ yyHour = $1;
+ yyMinutes = $3;
+ yyMeridian = MER24;
+ yyHaveZone++;
+ yyTimezone = ($4 < 0
+ ? -$4 % 100 + (-$4 / 100) * 60
+ : - ($4 % 100 + ($4 / 100) * 60));
+ }
+ | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
+ yyHour = $1;
+ yyMinutes = $3;
+ yySeconds = $5;
+ yyMeridian = $6;
+ }
+ | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
+ yyHour = $1;
+ yyMinutes = $3;
+ yySeconds = $5;
+ yyMeridian = MER24;
+ yyHaveZone++;
+ yyTimezone = ($6 < 0
+ ? -$6 % 100 + (-$6 / 100) * 60
+ : - ($6 % 100 + ($6 / 100) * 60));
+ }
+ ;
+
+zone : tZONE {
+ yyTimezone = $1;
+ }
+ | tDAYZONE {
+ yyTimezone = $1 - 60;
+ }
+ |
+ tZONE tDST {
+ yyTimezone = $1 - 60;
+ }
+ ;
+
+day : tDAY {
+ yyDayOrdinal = 1;
+ yyDayNumber = $1;
+ }
+ | tDAY ',' {
+ yyDayOrdinal = 1;
+ yyDayNumber = $1;
+ }
+ | tUNUMBER tDAY {
+ yyDayOrdinal = $1;
+ yyDayNumber = $2;
+ }
+ ;
+
+date : tUNUMBER '/' tUNUMBER {
+ yyMonth = $1;
+ yyDay = $3;
+ }
+ | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
+ /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
+ The goal in recognizing YYYY/MM/DD is solely to support legacy
+ machine-generated dates like those in an RCS log listing. If
+ you want portability, use the ISO 8601 format. */
+ if ($1 >= 1000)
+ {
+ yyYear = $1;
+ yyMonth = $3;
+ yyDay = $5;
+ }
+ else
+ {
+ yyMonth = $1;
+ yyDay = $3;
+ yyYear = $5;
+ }
+ }
+ | tUNUMBER tSNUMBER tSNUMBER {
+ /* ISO 8601 format. yyyy-mm-dd. */
+ yyYear = $1;
+ yyMonth = -$2;
+ yyDay = -$3;
+ }
+ | tUNUMBER tMONTH tSNUMBER {
+ /* e.g. 17-JUN-1992. */
+ yyDay = $1;
+ yyMonth = $2;
+ yyYear = -$3;
+ }
+ | tMONTH tUNUMBER {
+ yyMonth = $1;
+ yyDay = $2;
+ }
+ | tMONTH tUNUMBER ',' tUNUMBER {
+ yyMonth = $1;
+ yyDay = $2;
+ yyYear = $4;
+ }
+ | tUNUMBER tMONTH {
+ yyMonth = $2;
+ yyDay = $1;
+ }
+ | tUNUMBER tMONTH tUNUMBER {
+ yyMonth = $2;
+ yyDay = $1;
+ yyYear = $3;
+ }
+ ;
+
+rel : relunit tAGO {
+ yyRelSeconds = -yyRelSeconds;
+ yyRelMinutes = -yyRelMinutes;
+ yyRelHour = -yyRelHour;
+ yyRelDay = -yyRelDay;
+ yyRelMonth = -yyRelMonth;
+ yyRelYear = -yyRelYear;
+ }
+ | relunit
+ ;
+
+relunit : tUNUMBER tYEAR_UNIT {
+ yyRelYear += $1 * $2;
+ }
+ | tSNUMBER tYEAR_UNIT {
+ yyRelYear += $1 * $2;
+ }
+ | tYEAR_UNIT {
+ yyRelYear++;
+ }
+ | tUNUMBER tMONTH_UNIT {
+ yyRelMonth += $1 * $2;
+ }
+ | tSNUMBER tMONTH_UNIT {
+ yyRelMonth += $1 * $2;
+ }
+ | tMONTH_UNIT {
+ yyRelMonth++;
+ }
+ | tUNUMBER tDAY_UNIT {
+ yyRelDay += $1 * $2;
+ }
+ | tSNUMBER tDAY_UNIT {
+ yyRelDay += $1 * $2;
+ }
+ | tDAY_UNIT {
+ yyRelDay++;
+ }
+ | tUNUMBER tHOUR_UNIT {
+ yyRelHour += $1 * $2;
+ }
+ | tSNUMBER tHOUR_UNIT {
+ yyRelHour += $1 * $2;
+ }
+ | tHOUR_UNIT {
+ yyRelHour++;
+ }
+ | tUNUMBER tMINUTE_UNIT {
+ yyRelMinutes += $1 * $2;
+ }
+ | tSNUMBER tMINUTE_UNIT {
+ yyRelMinutes += $1 * $2;
+ }
+ | tMINUTE_UNIT {
+ yyRelMinutes++;
+ }
+ | tUNUMBER tSEC_UNIT {
+ yyRelSeconds += $1 * $2;
+ }
+ | tSNUMBER tSEC_UNIT {
+ yyRelSeconds += $1 * $2;
+ }
+ | tSEC_UNIT {
+ yyRelSeconds++;
+ }
+ ;
+
+number : tUNUMBER
+ {
+ if (yyHaveTime && yyHaveDate && !yyHaveRel)
+ yyYear = $1;
+ else
+ {
+ if ($1>10000)
+ {
+ yyHaveDate++;
+ yyDay= ($1)%100;
+ yyMonth= ($1/100)%100;
+ yyYear = $1/10000;
+ }
+ else
+ {
+ yyHaveTime++;
+ if ($1 < 100)
+ {
+ yyHour = $1;
+ yyMinutes = 0;
+ }
+ else
+ {
+ yyHour = $1 / 100;
+ yyMinutes = $1 % 100;
+ }
+ yySeconds = 0;
+ yyMeridian = MER24;
+ }
+ }
+ }
+ ;
+
+o_merid : /* NULL */
+ {
+ $$ = MER24;
+ }
+ | tMERIDIAN
+ {
+ $$ = $1;
+ }
+ ;
+
+%%
+
+/* Month and day table. */
+static TABLE const MonthDayTable[] = {
+ { "january", tMONTH, 1 },
+ { "february", tMONTH, 2 },
+ { "march", tMONTH, 3 },
+ { "april", tMONTH, 4 },
+ { "may", tMONTH, 5 },
+ { "june", tMONTH, 6 },
+ { "july", tMONTH, 7 },
+ { "august", tMONTH, 8 },
+ { "september", tMONTH, 9 },
+ { "sept", tMONTH, 9 },
+ { "october", tMONTH, 10 },
+ { "november", tMONTH, 11 },
+ { "december", tMONTH, 12 },
+ { "sunday", tDAY, 0 },
+ { "monday", tDAY, 1 },
+ { "tuesday", tDAY, 2 },
+ { "tues", tDAY, 2 },
+ { "wednesday", tDAY, 3 },
+ { "wednes", tDAY, 3 },
+ { "thursday", tDAY, 4 },
+ { "thur", tDAY, 4 },
+ { "thurs", tDAY, 4 },
+ { "friday", tDAY, 5 },
+ { "saturday", tDAY, 6 },
+ { NULL }
+};
+
+/* Time units table. */
+static TABLE const UnitsTable[] = {
+ { "year", tYEAR_UNIT, 1 },
+ { "month", tMONTH_UNIT, 1 },
+ { "fortnight", tDAY_UNIT, 14 },
+ { "week", tDAY_UNIT, 7 },
+ { "day", tDAY_UNIT, 1 },
+ { "hour", tHOUR_UNIT, 1 },
+ { "minute", tMINUTE_UNIT, 1 },
+ { "min", tMINUTE_UNIT, 1 },
+ { "second", tSEC_UNIT, 1 },
+ { "sec", tSEC_UNIT, 1 },
+ { NULL }
+};
+
+/* Assorted relative-time words. */
+static TABLE const OtherTable[] = {
+ { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
+ { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
+ { "today", tMINUTE_UNIT, 0 },
+ { "now", tMINUTE_UNIT, 0 },
+ { "last", tUNUMBER, -1 },
+ { "this", tMINUTE_UNIT, 0 },
+ { "next", tUNUMBER, 2 },
+ { "first", tUNUMBER, 1 },
+/* { "second", tUNUMBER, 2 }, */
+ { "third", tUNUMBER, 3 },
+ { "fourth", tUNUMBER, 4 },
+ { "fifth", tUNUMBER, 5 },
+ { "sixth", tUNUMBER, 6 },
+ { "seventh", tUNUMBER, 7 },
+ { "eighth", tUNUMBER, 8 },
+ { "ninth", tUNUMBER, 9 },
+ { "tenth", tUNUMBER, 10 },
+ { "eleventh", tUNUMBER, 11 },
+ { "twelfth", tUNUMBER, 12 },
+ { "ago", tAGO, 1 },
+ { NULL }
+};
+
+/* The timezone table. */
+static TABLE const TimezoneTable[] = {
+ { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */
+ { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
+ { "utc", tZONE, HOUR ( 0) },
+ { "wet", tZONE, HOUR ( 0) }, /* Western European */
+ { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */
+ { "wat", tZONE, HOUR ( 1) }, /* West Africa */
+ { "at", tZONE, HOUR ( 2) }, /* Azores */
+#if 0
+ /* For completeness. BST is also British Summer, and GST is
+ * also Guam Standard. */
+ { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */
+ { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */
+#endif
+#if 0
+ { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */
+ { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */
+ { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */
+#endif
+ { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */
+ { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */
+ { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */
+ { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */
+ { "cst", tZONE, HOUR ( 6) }, /* Central Standard */
+ { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */
+ { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */
+ { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */
+ { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */
+ { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */
+ { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */
+ { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */
+ { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */
+ { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */
+ { "cat", tZONE, HOUR (10) }, /* Central Alaska */
+ { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */
+ { "nt", tZONE, HOUR (11) }, /* Nome */
+ { "idlw", tZONE, HOUR (12) }, /* International Date Line West */
+ { "cet", tZONE, -HOUR (1) }, /* Central European */
+ { "met", tZONE, -HOUR (1) }, /* Middle European */
+ { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */
+ { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
+ { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
+ { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */
+ { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */
+ { "fwt", tZONE, -HOUR (1) }, /* French Winter */
+ { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */
+ { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */
+ { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */
+#if 0
+ { "it", tZONE, -HOUR (3.5) },/* Iran */
+#endif
+ { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */
+ { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */
+#if 0
+ { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */
+#endif
+ { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */
+#if 0
+ /* For completeness. NST is also Newfoundland Standard, and SST is
+ * also Swedish Summer. */
+ { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */
+ { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */
+#endif /* 0 */
+ { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */
+ { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */
+#if 0
+ { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */
+#endif
+ { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */
+ { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */
+#if 0
+ { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */
+ { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */
+#endif
+ { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */
+ { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */
+ { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */
+ { "nzt", tZONE, -HOUR (12) }, /* New Zealand */
+ { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */
+ { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */
+ { "idle", tZONE, -HOUR (12) }, /* International Date Line East */
+ { NULL }
+};
+
+/* Military timezone table. */
+static TABLE const MilitaryTable[] = {
+ { "a", tZONE, HOUR ( 1) },
+ { "b", tZONE, HOUR ( 2) },
+ { "c", tZONE, HOUR ( 3) },
+ { "d", tZONE, HOUR ( 4) },
+ { "e", tZONE, HOUR ( 5) },
+ { "f", tZONE, HOUR ( 6) },
+ { "g", tZONE, HOUR ( 7) },
+ { "h", tZONE, HOUR ( 8) },
+ { "i", tZONE, HOUR ( 9) },
+ { "k", tZONE, HOUR ( 10) },
+ { "l", tZONE, HOUR ( 11) },
+ { "m", tZONE, HOUR ( 12) },
+ { "n", tZONE, HOUR (- 1) },
+ { "o", tZONE, HOUR (- 2) },
+ { "p", tZONE, HOUR (- 3) },
+ { "q", tZONE, HOUR (- 4) },
+ { "r", tZONE, HOUR (- 5) },
+ { "s", tZONE, HOUR (- 6) },
+ { "t", tZONE, HOUR (- 7) },
+ { "u", tZONE, HOUR (- 8) },
+ { "v", tZONE, HOUR (- 9) },
+ { "w", tZONE, HOUR (-10) },
+ { "x", tZONE, HOUR (-11) },
+ { "y", tZONE, HOUR (-12) },
+ { "z", tZONE, HOUR ( 0) },
+ { NULL }
+};
+
+
+
+
+/* ARGSUSED */
+static int
+yyerror (s)
+ char *s;
+{
+ return 0;
+}
+
+static int
+ToHour (Hours, Meridian)
+ int Hours;
+ MERIDIAN Meridian;
+{
+ switch (Meridian)
+ {
+ case MER24:
+ if (Hours < 0 || Hours > 23)
+ return -1;
+ return Hours;
+ case MERam:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return Hours;
+ case MERpm:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return Hours + 12;
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+}
+
+static int
+ToYear (Year)
+ int Year;
+{
+ if (Year < 0)
+ Year = -Year;
+
+ /* XPG4 suggests that years 00-68 map to 2000-2068, and
+ years 69-99 map to 1969-1999. */
+ if (Year < 69)
+ Year += 2000;
+ else if (Year < 100)
+ Year += 1900;
+
+ return Year;
+}
+
+static int
+LookupWord (buff)
+ char *buff;
+{
+ register char *p;
+ register char *q;
+ register const TABLE *tp;
+ int i;
+ int abbrev;
+
+ /* Make it lowercase. */
+ for (p = buff; *p; p++)
+ if (ISUPPER (*p))
+ *p = tolower (*p);
+
+ if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
+ {
+ yylval.Meridian = MERam;
+ return tMERIDIAN;
+ }
+ if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0)
+ {
+ yylval.Meridian = MERpm;
+ return tMERIDIAN;
+ }
+
+ /* See if we have an abbreviation for a month. */
+ if (strlen (buff) == 3)
+ abbrev = 1;
+ else if (strlen (buff) == 4 && buff[3] == '.')
+ {
+ abbrev = 1;
+ buff[3] = '\0';
+ }
+ else
+ abbrev = 0;
+
+ for (tp = MonthDayTable; tp->name; tp++)
+ {
+ if (abbrev)
+ {
+ if (strncmp (buff, tp->name, 3) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+ else if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ if (strcmp (buff, "dst") == 0)
+ return tDST;
+
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Strip off any plural and try the units table again. */
+ i = strlen (buff) - 1;
+ if (buff[i] == 's')
+ {
+ buff[i] = '\0';
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ buff[i] = 's'; /* Put back for "this" in OtherTable. */
+ }
+
+ for (tp = OtherTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Military timezones. */
+ if (buff[1] == '\0' && ISALPHA (*buff))
+ {
+ for (tp = MilitaryTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ /* Drop out any periods and try the timezone table again. */
+ for (i = 0, p = q = buff; *q; q++)
+ if (*q != '.')
+ *p++ = *q;
+ else
+ i++;
+ *p = '\0';
+ if (i)
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp (buff, tp->name) == 0)
+ {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ return tID;
+}
+
+static int
+yylex ()
+{
+ register char c;
+ register char *p;
+ char buff[20];
+ int Count;
+ int sign;
+
+ for (;;)
+ {
+ while (ISSPACE (*yyInput))
+ yyInput++;
+
+ if (ISDIGIT (c = *yyInput) || c == '-' || c == '+')
+ {
+ if (c == '-' || c == '+')
+ {
+ sign = c == '-' ? -1 : 1;
+ if (!ISDIGIT (*++yyInput))
+ /* skip the '-' sign */
+ continue;
+ }
+ else
+ sign = 0;
+ for (yylval.Number = 0; ISDIGIT (c = *yyInput++);)
+ yylval.Number = 10 * yylval.Number + c - '0';
+ yyInput--;
+ if (sign < 0)
+ yylval.Number = -yylval.Number;
+ return sign ? tSNUMBER : tUNUMBER;
+ }
+ if (ISALPHA (c))
+ {
+ for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';)
+ if (p < &buff[sizeof buff - 1])
+ *p++ = c;
+ *p = '\0';
+ yyInput--;
+ return LookupWord (buff);
+ }
+ if (c != '(')
+ return *yyInput++;
+ Count = 0;
+ do
+ {
+ c = *yyInput++;
+ if (c == '\0')
+ return c;
+ if (c == '(')
+ Count++;
+ else if (c == ')')
+ Count--;
+ }
+ while (Count > 0);
+ }
+}
+
+#define TM_YEAR_ORIGIN 1900
+
+/* Yield A - B, measured in seconds. */
+static long
+difftm (a, b)
+ struct tm *a, *b;
+{
+ int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
+ int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
+ long days = (
+ /* difference in day of year */
+ a->tm_yday - b->tm_yday
+ /* + intervening leap days */
+ + ((ay >> 2) - (by >> 2))
+ - (ay / 100 - by / 100)
+ + ((ay / 100 >> 2) - (by / 100 >> 2))
+ /* + difference in years * 365 */
+ + (long) (ay - by) * 365
+ );
+ return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+
+time_t
+get_date (p, now)
+ const char *p;
+ const time_t *now;
+{
+ struct tm tm, tm0, *tmp;
+ time_t Start;
+
+ yyInput = p;
+ Start = now ? *now : time ((time_t *) NULL);
+ tmp = localtime (&Start);
+ yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
+ yyMonth = tmp->tm_mon + 1;
+ yyDay = tmp->tm_mday;
+ yyHour = tmp->tm_hour;
+ yyMinutes = tmp->tm_min;
+ yySeconds = tmp->tm_sec;
+ yyMeridian = MER24;
+ yyRelSeconds = 0;
+ yyRelMinutes = 0;
+ yyRelHour = 0;
+ yyRelDay = 0;
+ yyRelMonth = 0;
+ yyRelYear = 0;
+ yyHaveDate = 0;
+ yyHaveDay = 0;
+ yyHaveRel = 0;
+ yyHaveTime = 0;
+ yyHaveZone = 0;
+
+ if (yyparse ()
+ || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
+ return -1;
+
+ tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
+ tm.tm_mon = yyMonth - 1 + yyRelMonth;
+ tm.tm_mday = yyDay + yyRelDay;
+ if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay))
+ {
+ tm.tm_hour = ToHour (yyHour, yyMeridian);
+ if (tm.tm_hour < 0)
+ return -1;
+ tm.tm_min = yyMinutes;
+ tm.tm_sec = yySeconds;
+ }
+ else
+ {
+ tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ }
+ tm.tm_hour += yyRelHour;
+ tm.tm_min += yyRelMinutes;
+ tm.tm_sec += yyRelSeconds;
+ tm.tm_isdst = -1;
+ tm0 = tm;
+
+ Start = mktime (&tm);
+
+ if (Start == (time_t) -1)
+ {
+
+ /* Guard against falsely reporting errors near the time_t boundaries
+ when parsing times in other time zones. For example, if the min
+ time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
+ of UTC, then the min localtime value is 1970-01-01 08:00:00; if
+ we apply mktime to 1970-01-01 00:00:00 we will get an error, so
+ we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
+ zone by 24 hours to compensate. This algorithm assumes that
+ there is no DST transition within a day of the time_t boundaries. */
+ if (yyHaveZone)
+ {
+ tm = tm0;
+ if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
+ {
+ tm.tm_mday++;
+ yyTimezone -= 24 * 60;
+ }
+ else
+ {
+ tm.tm_mday--;
+ yyTimezone += 24 * 60;
+ }
+ Start = mktime (&tm);
+ }
+
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (yyHaveDay && !yyHaveDate)
+ {
+ tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
+ + 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
+ Start = mktime (&tm);
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (yyHaveZone)
+ {
+ long delta = yyTimezone * 60L + difftm (&tm, gmtime (&Start));
+ if ((Start + delta < Start) != (delta < 0))
+ return -1; /* time_t overflow */
+ Start += delta;
+ }
+
+ return Start;
+}
+
+#if defined (TEST)
+
+/* ARGSUSED */
+int
+main (ac, av)
+ int ac;
+ char *av[];
+{
+ char buff[MAX_BUFF_LEN + 1];
+ time_t d;
+
+ (void) printf ("Enter date, or blank line to exit.\n\t> ");
+ (void) fflush (stdout);
+
+ buff[MAX_BUFF_LEN] = 0;
+ while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
+ {
+ d = get_date (buff, (time_t *) NULL);
+ if (d == -1)
+ (void) printf ("Bad format - couldn't convert.\n");
+ else
+ (void) printf ("%s", ctime (&d));
+ (void) printf ("\t> ");
+ (void) fflush (stdout);
+ }
+ exit (0);
+ /* NOTREACHED */
+}
+#endif /* defined (TEST) */
diff --git a/current/libmisc/hushed.c b/current/libmisc/hushed.c
new file mode 100644
index 00000000..fbc7a19d
--- /dev/null
+++ b/current/libmisc/hushed.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1991, 1993, Julianne Frances Haugh and Chip Rosenthal
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: hushed.c,v 1.4 2000/08/26 18:27:17 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "defines.h"
+#include "prototypes.h"
+#include "getdef.h"
+#include <pwd.h>
+
+/*
+ * hushed - determine if a user receives login messages
+ *
+ * Look in the hushed-logins file (or user's home directory) to see
+ * if the user is to receive the login-time messages.
+ */
+
+int
+hushed(const struct passwd *pw)
+{
+ char *hushfile;
+ char buf[BUFSIZ];
+ int found;
+ FILE *fp;
+
+ /*
+ * Get the name of the file to use. If this option is not
+ * defined, default to a noisy login.
+ */
+
+ if ( (hushfile=getdef_str("HUSHLOGIN_FILE")) == NULL )
+ return 0;
+
+ /*
+ * If this is not a fully rooted path then see if the
+ * file exists in the user's home directory.
+ */
+
+ if (hushfile[0] != '/') {
+ snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, hushfile);
+ return (access(buf, F_OK) == 0);
+ }
+
+ /*
+ * If this is a fully rooted path then go through the file
+ * and see if this user is in there.
+ */
+
+ if ((fp = fopen(hushfile, "r")) == NULL)
+ return 0;
+
+ for (found = 0;! found && fgets (buf, sizeof buf, fp);) {
+ buf[strlen (buf) - 1] = '\0';
+ found = ! strcmp (buf,
+ buf[0] == '/' ? pw->pw_shell:pw->pw_name);
+ }
+ (void) fclose(fp);
+ return found;
+}
diff --git a/current/libmisc/isexpired.c b/current/libmisc/isexpired.c
new file mode 100644
index 00000000..d70b2a79
--- /dev/null
+++ b/current/libmisc/isexpired.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Extracted from age.c and made part of libshadow.a - may be useful
+ * in other shadow-aware programs. --marekm
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include <time.h>
+
+#ifdef HAVE_USERSEC_H
+#include <userpw.h>
+#include <usersec.h>
+#include <userconf.h>
+#endif
+
+#ifndef AGING
+#if defined(SHADOWPWD) || defined(HAVE_USERSEC_H)
+#define AGING 1
+#endif
+#else
+#if !defined(SHADOWPWD) && !defined(HAVE_USERSEC_H) && !defined(ATT_AGE)
+#undef AGING
+#endif
+#endif
+
+#if defined(SHADOWPWD) || defined(AGING) /*{*/
+
+#include "rcsid.h"
+RCSID("$Id: isexpired.c,v 1.7 1997/12/07 23:27:05 marekm Exp $")
+
+/*
+ * isexpired - determine if account is expired yet
+ *
+ * isexpired calculates the expiration date based on the
+ * password expiration criteria.
+ */
+
+/*ARGSUSED*/
+
+#ifdef SHADOWPWD
+int
+isexpired(const struct passwd *pw, const struct spwd *sp)
+{
+#else
+int
+isexpired(const struct passwd *pw)
+{
+#endif
+ long now;
+#ifdef HAVE_USERSEC_H
+ int minage = 0;
+ int maxage = 10000;
+ int curage = 0;
+ struct userpw *pu;
+#endif
+
+ now = time ((time_t *) 0) / SCALE;
+
+#ifdef SHADOWPWD
+
+ if (!sp)
+ sp = pwd_to_spwd(pw);
+
+ /*
+ * Quick and easy - there is an expired account field
+ * along with an inactive account field. Do the expired
+ * one first since it is worse.
+ */
+
+ if (sp->sp_expire > 0 && now >= sp->sp_expire)
+ return 3;
+
+ /*
+ * Last changed date 1970-01-01 (not very likely) means that
+ * the password must be changed on next login (passwd -e).
+ *
+ * The check for "x" is a workaround for RedHat NYS libc bug -
+ * if /etc/shadow doesn't exist, getspnam() still succeeds and
+ * returns sp_lstchg==0 (must change password) instead of -1!
+ */
+ if (sp->sp_lstchg == 0 && !strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING))
+ return 1;
+
+ if (sp->sp_lstchg > 0 && sp->sp_max >= 0 && sp->sp_inact >= 0 &&
+ now >= sp->sp_lstchg + sp->sp_max + sp->sp_inact)
+ return 2;
+#endif
+#ifdef HAVE_USERSEC_H /*{*/
+ /*
+ * The aging information lives someplace else. Get it from the
+ * login.cfg file
+ */
+
+ if (getconfattr (SC_SYS_PASSWD, SC_MINAGE, &minage, SEC_INT))
+ minage = -1;
+
+ if (getconfattr (SC_SYS_PASSWD, SC_MAXAGE, &maxage, SEC_INT))
+ maxage = -1;
+
+ pu = getuserpw (pw->pw_name);
+ curage = (time (0) - pu->upw_lastupdate) / (7*86400L);
+
+ if (maxage != -1 && curage > maxage)
+ return 1;
+#else /*} !HAVE_USERSEC_H */
+
+ /*
+ * The last and max fields must be present for an account
+ * to have an expired password. A maximum of >10000 days
+ * is considered to be infinite.
+ */
+
+#ifdef SHADOWPWD
+ if (sp->sp_lstchg == -1 ||
+ sp->sp_max == -1 || sp->sp_max >= (10000L*DAY/SCALE))
+ return 0;
+#endif
+#ifdef ATT_AGE
+ if (pw->pw_age[0] == '\0' || pw->pw_age[0] == '/')
+ return 0;
+#endif
+
+ /*
+ * Calculate today's day and the day on which the password
+ * is going to expire. If that date has already passed,
+ * the password has expired.
+ */
+
+#ifdef SHADOWPWD
+ if (now >= sp->sp_lstchg + sp->sp_max)
+ return 1;
+#endif
+#ifdef ATT_AGE
+ if (a64l (pw->pw_age + 2) + c64i (pw->pw_age[1]) < now / 7)
+ return 1;
+#endif
+#endif /*} HAVE_USERSEC_H */
+ return 0;
+}
+#endif /*}*/
diff --git a/current/libmisc/limits.c b/current/libmisc/limits.c
new file mode 100644
index 00000000..e17817ea
--- /dev/null
+++ b/current/libmisc/limits.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Separated from setup.c. --marekm
+ * Resource limits thanks to Cristian Gafton.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: limits.c,v 1.10 1999/08/27 19:02:51 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include "getdef.h"
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#define LIMITS
+#endif
+
+#ifdef LIMITS
+
+#ifndef LIMITS_FILE
+#define LIMITS_FILE "/etc/limits"
+#endif
+
+#define LOGIN_ERROR_RLIMIT 1
+#define LOGIN_ERROR_LOGIN 2
+
+/* Set a limit on a resource */
+/*
+ * rlimit - RLIMIT_XXXX
+ * value - string value to be read
+ * multiplier - value*multiplier is the actual limit
+ */
+static int
+setrlimit_value(unsigned int rlimit, const char *value, unsigned int multiplier)
+{
+ struct rlimit rlim;
+ long limit;
+ char **endptr = (char **) &value;
+ const char *value_orig = value;
+
+ limit = strtol(value, endptr, 10);
+ if (limit == 0 && value_orig == *endptr) /* no chars read */
+ return 0;
+ limit *= multiplier;
+ rlim.rlim_cur = limit;
+ rlim.rlim_max = limit;
+ if (setrlimit(rlimit, &rlim))
+ return LOGIN_ERROR_RLIMIT;
+ return 0;
+}
+
+
+static int
+set_prio(const char *value)
+{
+ int prio;
+ char **endptr = (char **) &value;
+
+ prio = strtol(value, endptr, 10);
+ if ((prio == 0) && (value == *endptr))
+ return 0;
+ if (setpriority(PRIO_PROCESS, 0, prio))
+ return LOGIN_ERROR_RLIMIT;
+ return 0;
+}
+
+
+static int
+set_umask(const char *value)
+{
+ mode_t mask;
+ char **endptr = (char **) &value;
+
+ mask = strtol(value, endptr, 8) & 0777;
+ if ((mask == 0) && (value == *endptr))
+ return 0;
+ umask(mask);
+ return 0;
+}
+
+
+/* Counts the number of user logins and check against the limit */
+static int
+check_logins(const char *name, const char *maxlogins)
+{
+ struct utmp *ut;
+ unsigned int limit, count;
+ char **endptr = (char **) &maxlogins;
+ const char *ml_orig = maxlogins;
+
+ limit = strtol(maxlogins, endptr, 10);
+ if (limit == 0 && ml_orig == *endptr) /* no chars read */
+ return 0;
+
+ if (limit == 0) /* maximum 0 logins ? */ {
+ SYSLOG((LOG_WARN, "No logins allowed for `%s'\n", name));
+ return LOGIN_ERROR_LOGIN;
+ }
+
+ setutent();
+ count = 0;
+ while ((ut = getutent())) {
+#ifdef USER_PROCESS
+ if (ut->ut_type != USER_PROCESS)
+ continue;
+#endif
+ if (ut->ut_user[0] == '\0')
+ continue;
+ if (strncmp(name, ut->ut_user, sizeof(ut->ut_user)) != 0)
+ continue;
+ if (++count > limit)
+ break;
+ }
+ endutent();
+ /*
+ * This is called after setutmp(), so the number of logins counted
+ * includes the user who is currently trying to log in.
+ */
+ if (count > limit) {
+ SYSLOG((LOG_WARN, "Too many logins (max %d) for %s\n",
+ limit, name));
+ return LOGIN_ERROR_LOGIN;
+ }
+ return 0;
+}
+
+/* Function setup_user_limits - checks/set limits for the curent login
+ * Original idea from Joel Katz's lshell. Ported to shadow-login
+ * by Cristian Gafton - gafton@sorosis.ro
+ *
+ * We are passed a string of the form ('BASH' constants for ulimit)
+ * [Aa][Cc][Dd][Ff][Mm][Nn][Rr][Ss][Tt][Uu][Ll][Pp]
+ * (eg. 'C2F256D2048N5' or 'C2 F256 D2048 N5')
+ * where:
+ * [Aa]: a = RLIMIT_AS max address space (KB)
+ * [Cc]: c = RLIMIT_CORE max core file size (KB)
+ * [Dd]: d = RLIMIT_DATA max data size (KB)
+ * [Ff]: f = RLIMIT_FSIZE max file size (KB)
+ * [Mm]: m = RLIMIT_MEMLOCK max locked-in-memory address space (KB)
+ * [Nn]: n = RLIMIT_NOFILE max number of open files
+ * [Rr]: r = RLIMIT_RSS max resident set size (KB)
+ * [Ss]: s = RLIMIT_STACK max stack size (KB)
+ * [Tt]: t = RLIMIT_CPU max CPU time (MIN)
+ * [Uu]: u = RLIMIT_NPROC max number of processes
+ * [Kk]: k = file creation masK (umask)
+ * [Ll]: l = max number of logins for this user
+ * [Pp]: p = process priority -20..20 (negative = high, positive = low)
+ *
+ * Return value:
+ * 0 = okay, of course
+ * LOGIN_ERROR_RLIMIT = error setting some RLIMIT
+ * LOGIN_ERROR_LOGIN = error - too many logins for this user
+ *
+ * buf - the limits string
+ * name - the username
+ */
+static int
+do_user_limits(const char *buf, const char *name)
+{
+ const char *pp;
+ int retval = 0;
+
+ pp = buf;
+
+ while (*pp != '\0') switch(*pp++) {
+#ifdef RLIMIT_AS
+ case 'a':
+ case 'A':
+ /* RLIMIT_AS - max address space (KB) */
+ retval |= setrlimit_value(RLIMIT_AS, pp, 1024);
+#endif
+#ifdef RLIMIT_CPU
+ case 't':
+ case 'T':
+ /* RLIMIT_CPU - max CPU time (MIN) */
+ retval |= setrlimit_value(RLIMIT_CPU, pp, 60);
+ break;
+#endif
+#ifdef RLIMIT_DATA
+ case 'd':
+ case 'D':
+ /* RLIMIT_DATA - max data size (KB) */
+ retval |= setrlimit_value(RLIMIT_DATA, pp, 1024);
+ break;
+#endif
+#ifdef RLIMIT_FSIZE
+ case 'f':
+ case 'F':
+ /* RLIMIT_FSIZE - Maximum filesize (KB) */
+ retval |= setrlimit_value(RLIMIT_FSIZE, pp, 1024);
+ break;
+#endif
+#ifdef RLIMIT_NPROC
+ case 'u':
+ case 'U':
+ /* RLIMIT_NPROC - max number of processes */
+ retval |= setrlimit_value(RLIMIT_NPROC, pp, 1);
+ break;
+#endif
+#ifdef RLIMIT_CORE
+ case 'c':
+ case 'C':
+ /* RLIMIT_CORE - max core file size (KB) */
+ retval |= setrlimit_value(RLIMIT_CORE, pp, 1024);
+ break;
+#endif
+#ifdef RLIMIT_MEMLOCK
+ case 'm':
+ case 'M':
+ /* RLIMIT_MEMLOCK - max locked-in-memory address space (KB) */
+ retval |= setrlimit_value(RLIMIT_MEMLOCK, pp, 1024);
+ break;
+#endif
+#ifdef RLIMIT_NOFILE
+ case 'n':
+ case 'N':
+ /* RLIMIT_NOFILE - max number of open files */
+ retval |= setrlimit_value(RLIMIT_NOFILE, pp, 1);
+ break;
+#endif
+#ifdef RLIMIT_RSS
+ case 'r':
+ case 'R':
+ /* RLIMIT_RSS - max resident set size (KB) */
+ retval |= setrlimit_value(RLIMIT_RSS, pp, 1024);
+ break;
+#endif
+#ifdef RLIMIT_STACK
+ case 's':
+ case 'S':
+ /* RLIMIT_STACK - max stack size (KB) */
+ retval |= setrlimit_value(RLIMIT_STACK, pp, 1024);
+ break;
+#endif
+ case 'k':
+ case 'K':
+ retval |= set_umask(pp);
+ break;
+ case 'l':
+ case 'L':
+ /* LIMIT the number of concurent logins */
+ retval |= check_logins(name, pp);
+ break;
+ case 'p':
+ case 'P':
+ retval |= set_prio(pp);
+ break;
+ }
+ return retval;
+}
+
+static int
+setup_user_limits(const char *uname)
+{
+ /* TODO: allow and use @group syntax --cristiang */
+ FILE *fil;
+ char buf[1024];
+ char name[1024];
+ char limits[1024];
+ char deflimits[1024];
+ char tempbuf[1024];
+
+ /* init things */
+ memzero(buf, sizeof(buf));
+ memzero(name, sizeof(name));
+ memzero(limits, sizeof(limits));
+ memzero(deflimits, sizeof(deflimits));
+ memzero(tempbuf, sizeof(tempbuf));
+
+ /* start the checks */
+ fil = fopen(LIMITS_FILE, "r");
+ if (fil == NULL) {
+#if 0 /* no limits file is ok, not everyone is a BOFH :-). --marekm */
+ SYSLOG((LOG_WARN, NO_LIMITS, uname, LIMITS_FILE));
+#endif
+ return 0;
+ }
+ /* The limits file have the following format:
+ * - '#' (comment) chars only as first chars on a line;
+ * - username must start on first column
+ * A better (smarter) checking should be done --cristiang */
+ while (fgets(buf, 1024, fil) != NULL) {
+ if (buf[0]=='#' || buf[0]=='\n')
+ continue;
+ memzero(tempbuf, sizeof(tempbuf));
+ /* a valid line should have a username, then spaces,
+ * then limits
+ * we allow the format:
+ * username L2 D2048 R4096
+ * where spaces={' ',\t}. Also, we reject invalid limits.
+ * Imposing a limit should be done with care, so a wrong
+ * entry means no care anyway :-). A '-' as a limits
+ * strings means no limits --cristiang */
+ if (sscanf(buf, "%s%[ACDFMNRSTULPacdfmnrstulp0-9 \t-]",
+ name, tempbuf) == 2) {
+ if (strcmp(name, uname) == 0) {
+ strcpy(limits, tempbuf);
+ break;
+ } else if (strcmp(name, "*") == 0) {
+ strcpy(deflimits, tempbuf);
+ }
+ }
+ }
+ fclose(fil);
+ if (limits[0] == '\0') {
+ /* no user specific limits */
+ if (deflimits[0] == '\0') /* no default limits */
+ return 0;
+ strcpy(limits, deflimits); /* use the default limits */
+ }
+ return do_user_limits(limits, uname);
+}
+#endif /* LIMITS */
+
+
+static void
+setup_usergroups(const struct passwd *info)
+{
+ const struct group *grp;
+ mode_t oldmask;
+
+/*
+ * if not root, and uid == gid, and username is the same as primary
+ * group name, set umask group bits to be the same as owner bits
+ * (examples: 022 -> 002, 077 -> 007).
+ */
+ if (info->pw_uid != 0 && info->pw_uid == info->pw_gid) {
+ grp = getgrgid(info->pw_gid);
+ if (grp && (strcmp(info->pw_name, grp->gr_name) == 0)) {
+ oldmask = umask(0777);
+ umask((oldmask & ~070) | ((oldmask >> 3) & 070));
+ }
+ }
+}
+
+/*
+ * set the process nice, ulimit, and umask from the password file entry
+ */
+
+void
+setup_limits(const struct passwd *info)
+{
+ char *cp;
+ int i;
+ long l;
+
+ if (getdef_bool("USERGROUPS_ENAB"))
+ setup_usergroups(info);
+
+ /*
+ * See if the GECOS field contains values for NICE, UMASK or ULIMIT.
+ * If this feature is enabled in /etc/login.defs, we make those
+ * values the defaults for this login session.
+ */
+
+ if (getdef_bool("QUOTAS_ENAB")) {
+#ifdef LIMITS
+ if (info->pw_uid != 0)
+ if (setup_user_limits(info->pw_name) & LOGIN_ERROR_LOGIN) {
+ fprintf(stderr, _("Too many logins.\n"));
+ sleep(2);
+ exit(1);
+ }
+#endif
+ for (cp = info->pw_gecos ; cp != NULL ; cp = strchr (cp, ',')) {
+ if (*cp == ',')
+ cp++;
+
+ if (strncmp (cp, "pri=", 4) == 0) {
+ i = atoi (cp + 4);
+ if (i >= -20 && i <= 20)
+ (void) nice (i);
+
+ continue;
+ }
+ if (strncmp (cp, "ulimit=", 7) == 0) {
+ l = strtol (cp + 7, (char **) 0, 10);
+ set_filesize_limit(l);
+ continue;
+ }
+ if (strncmp (cp, "umask=", 6) == 0) {
+ i = strtol (cp + 6, (char **) 0, 8) & 0777;
+ (void) umask (i);
+
+ continue;
+ }
+ }
+ }
+}
diff --git a/current/libmisc/list.c b/current/libmisc/list.c
new file mode 100644
index 00000000..db63c8dc
--- /dev/null
+++ b/current/libmisc/list.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Removed duplicated code from gpmain.c, useradd.c, userdel.c and
+ usermod.c. --marekm */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: list.c,v 1.3 1997/12/07 23:27:05 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+
+/*
+ * add_list - add a member to a list of group members
+ *
+ * the array of member names is searched for the new member
+ * name, and if not present it is added to a freshly allocated
+ * list of users.
+ */
+
+char **
+add_list(char **list, const char *member)
+{
+ int i;
+ char **tmp;
+
+ /*
+ * Scan the list for the new name. Return the original list
+ * pointer if it is present.
+ */
+
+ for (i = 0;list[i] != (char *) 0;i++)
+ if (strcmp (list[i], member) == 0)
+ return list;
+
+ /*
+ * Allocate a new list pointer large enough to hold all the
+ * old entries, and the new entries as well.
+ */
+
+ tmp = (char **) xmalloc ((i + 2) * sizeof member);
+
+ /*
+ * Copy the original list to the new list, then append the
+ * new member and NULL terminate the result. This new list
+ * is returned to the invoker.
+ */
+
+ for (i = 0;list[i] != (char *) 0;i++)
+ tmp[i] = list[i];
+
+ tmp[i++] = xstrdup (member);
+ tmp[i] = (char *) 0;
+
+ return tmp;
+}
+
+/*
+ * del_list - delete a member from a list of group members
+ *
+ * the array of member names is searched for the old member
+ * name, and if present it is deleted from a freshly allocated
+ * list of users.
+ */
+
+char **
+del_list(char **list, const char *member)
+{
+ int i, j;
+ char **tmp;
+
+ /*
+ * Scan the list for the old name. Return the original list
+ * pointer if it is not present.
+ */
+
+ for (i = j = 0;list[i] != (char *) 0;i++)
+ if (strcmp (list[i], member))
+ j++;
+
+ if (j == i)
+ return list;
+
+ /*
+ * Allocate a new list pointer large enough to hold all the
+ * old entries.
+ */
+
+ tmp = (char **) xmalloc ((j + 1) * sizeof member);
+
+ /*
+ * Copy the original list except the deleted members to the
+ * new list, then NULL terminate the result. This new list
+ * is returned to the invoker.
+ */
+
+ for (i = j = 0;list[i] != (char *) 0;i++)
+ if (strcmp (list[i], member))
+ tmp[j++] = list[i];
+
+ tmp[j] = (char *) 0;
+
+ return tmp;
+}
+
+char **
+dup_list(char * const *list)
+{
+ int i;
+ char **tmp;
+
+ for (i = 0; list[i]; i++)
+ ;
+
+ tmp = (char **) xmalloc((i + 1) * sizeof(char *));
+
+ i = 0;
+ while (*list)
+ tmp[i++] = xstrdup(*list++);
+
+ tmp[i] = (char *) 0;
+ return tmp;
+}
+
+int
+is_on_list(char * const *list, const char *member)
+{
+ while (*list) {
+ if (strcmp(*list, member) == 0)
+ return 1;
+ list++;
+ }
+ return 0;
+}
+
+/*
+ * comma_to_list - convert comma-separated list to (char *) array
+ */
+
+char **
+comma_to_list(const char *comma)
+{
+ char *members;
+ char **array;
+ int i;
+ char *cp, *cp2;
+
+ /*
+ * Make a copy since we are going to be modifying the list
+ */
+
+ members = xstrdup (comma);
+
+ /*
+ * Count the number of commas in the list
+ */
+
+ for (cp = members, i = 0;;i++)
+ if ((cp2 = strchr (cp, ',')))
+ cp = cp2 + 1;
+ else
+ break;
+
+ /*
+ * Add 2 - one for the ending NULL, the other for the last item
+ */
+
+ i += 2;
+
+ /*
+ * Allocate the array we're going to store the pointers into.
+ */
+
+ array = (char **) xmalloc (sizeof (char *) * i);
+
+ /*
+ * Empty list is special - 0 members, not 1 empty member. --marekm
+ */
+
+ if (!*members) {
+ *array = (char *) 0;
+ return array;
+ }
+
+ /*
+ * Now go walk that list all over again, this time building the
+ * array of pointers.
+ */
+
+ for (cp = members, i = 0;;i++) {
+ array[i] = cp;
+ if ((cp2 = strchr (cp, ','))) {
+ *cp2++ = '\0';
+ cp = cp2;
+ } else {
+ array[i + 1] = (char *) 0;
+ break;
+ }
+ }
+
+ /*
+ * Return the new array of pointers
+ */
+
+ return array;
+}
diff --git a/current/libmisc/log.c b/current/libmisc/log.c
new file mode 100644
index 00000000..a0ee0e1b
--- /dev/null
+++ b/current/libmisc/log.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: log.c,v 1.5 1998/04/16 19:57:44 marekm Exp $")
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <time.h>
+#include "defines.h"
+#if HAVE_LASTLOG_H
+#include <lastlog.h>
+#else
+#include "lastlog_.h"
+#endif
+
+/*
+ * dolastlog - create lastlog entry
+ *
+ * A "last login" entry is created for the user being logged in. The
+ * UID is extracted from the global (struct passwd) entry and the
+ * TTY information is gotten from the (struct utmp).
+ */
+
+void
+dolastlog(struct lastlog *ll, const struct passwd *pw, const char *line, const char *host)
+{
+ int fd;
+ off_t offset;
+ struct lastlog newlog;
+
+ /*
+ * If the file does not exist, don't create it.
+ */
+
+ if ((fd = open(LASTLOG_FILE, O_RDWR)) == -1)
+ return;
+
+ /*
+ * The file is indexed by UID number. Seek to the record
+ * for this UID. Negative UID's will create problems, but ...
+ */
+
+ offset = (unsigned long) pw->pw_uid * sizeof newlog;
+
+ if (lseek(fd, offset, SEEK_SET) != offset) {
+ close(fd);
+ return;
+ }
+
+ /*
+ * Read the old entry so we can tell the user when they last
+ * logged in. Then construct the new entry and write it out
+ * the way we read the old one in.
+ */
+
+ if (read(fd, (char *) &newlog, sizeof newlog) != sizeof newlog)
+ memzero(&newlog, sizeof newlog);
+ if (ll)
+ *ll = newlog;
+
+ time(&newlog.ll_time);
+ strncpy(newlog.ll_line, line, sizeof newlog.ll_line);
+#if HAVE_LL_HOST
+ strncpy(newlog.ll_host, host, sizeof newlog.ll_host);
+#endif
+ if (lseek(fd, offset, SEEK_SET) == offset)
+ write(fd, (char *) &newlog, sizeof newlog);
+ close(fd);
+}
+
diff --git a/current/libmisc/login_access.c b/current/libmisc/login_access.c
new file mode 100644
index 00000000..1d06d3e7
--- /dev/null
+++ b/current/libmisc/login_access.c
@@ -0,0 +1,340 @@
+/* Taken from logdaemon-5.0, only minimal changes. --marekm */
+
+/************************************************************************
+* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+* may be covered by other copyrights (as noted in the file itself.)
+*
+* This material was originally written and compiled by Wietse Venema at
+* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+* 1992, 1993, 1994 and 1995.
+*
+* Redistribution and use in source and binary forms are permitted
+* provided that this entire copyright notice is duplicated in all such
+* copies.
+*
+* This software is provided "as is" and without any expressed or implied
+* warranties, including, without limitation, the implied warranties of
+* merchantibility and fitness for any particular purpose.
+************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef LOGIN_ACCESS
+#include "rcsid.h"
+RCSID("$Id: login_access.c,v 1.6 1998/01/29 23:22:34 marekm Exp $")
+#include "prototypes.h"
+
+ /*
+ * This module implements a simple but effective form of login access
+ * control based on login names and on host (or domain) names, internet
+ * addresses (or network numbers), or on terminal line names in case of
+ * non-networked logins. Diagnostics are reported through syslog(3).
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <grp.h>
+#ifdef PRIMARY_GROUP_MATCH
+#include <pwd.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h> /* for inet_ntoa() */
+
+extern struct group *getgrnam();
+extern int innetgr();
+#if 0 /* should be defined by <errno.h> */
+extern int errno;
+#endif
+
+#if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64)
+#undef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+ /* Path name of the access control file. */
+
+#ifndef TABLE
+#define TABLE "/etc/login.access"
+#endif
+
+ /* Delimiters for fields and for lists of users, ttys or hosts. */
+
+static char fs[] = ":"; /* field separator */
+static char sep[] = ", \t"; /* list-element separator */
+
+ /* Constants to be used in assignments only, not in comparisons... */
+
+#define YES 1
+#define NO 0
+
+static int list_match();
+static int user_match();
+static int from_match();
+static int string_match();
+
+/* login_access - match username/group and host/tty with access control file */
+
+int
+login_access(const char *user, const char *from)
+{
+ FILE *fp;
+ char line[BUFSIZ];
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
+ int match = NO;
+ int end;
+ int lineno = 0; /* for diagnostics */
+
+ /*
+ * Process the table one line at a time and stop at the first match.
+ * Blank lines and lines that begin with a '#' character are ignored.
+ * Non-comment lines are broken at the ':' character. All fields are
+ * mandatory. The first field should be a "+" or "-" character. A
+ * non-existing table means no access control.
+ */
+
+ if ((fp = fopen(TABLE, "r"))) {
+ while (!match && fgets(line, sizeof(line), fp)) {
+ lineno++;
+ if (line[end = strlen(line) - 1] != '\n') {
+ syslog(LOG_ERR, "%s: line %d: missing newline or line too long",
+ TABLE, lineno);
+ continue;
+ }
+ if (line[0] == '#')
+ continue; /* comment line */
+ while (end > 0 && isspace(line[end - 1]))
+ end--;
+ line[end] = 0; /* strip trailing whitespace */
+ if (line[0] == 0) /* skip blank lines */
+ continue;
+ if (!(perm = strtok(line, fs))
+ || !(users = strtok((char *) 0, fs))
+ || !(froms = strtok((char *) 0, fs))
+ || strtok((char *) 0, fs)) {
+ syslog(LOG_ERR, "%s: line %d: bad field count", TABLE, lineno);
+ continue;
+ }
+ if (perm[0] != '+' && perm[0] != '-') {
+ syslog(LOG_ERR, "%s: line %d: bad first field", TABLE, lineno);
+ continue;
+ }
+ match = (list_match(froms, from, from_match)
+ && list_match(users, user, user_match));
+ }
+ (void) fclose(fp);
+ } else if (errno != ENOENT) {
+ syslog(LOG_ERR, "cannot open %s: %m", TABLE);
+ }
+ return (match == 0 || (line[0] == '+'));
+}
+
+/* list_match - match an item against a list of tokens with exceptions */
+
+static int
+list_match(char *list, const char *item, int (*match_fn)())
+{
+ char *tok;
+ int match = NO;
+
+ /*
+ * Process tokens one at a time. We have exhausted all possible matches
+ * when we reach an "EXCEPT" token or the end of the list. If we do find
+ * a match, look for an "EXCEPT" list and recurse to determine whether
+ * the match is affected by any exceptions.
+ */
+
+ for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
+ if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
+ break;
+ if ((match = (*match_fn) (tok, item))) /* YES */
+ break;
+ }
+ /* Process exceptions to matches. */
+
+ if (match != NO) {
+ while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
+ /* VOID */ ;
+ if (tok == 0 || list_match((char *) 0, item, match_fn) == NO)
+ return (match);
+ }
+ return (NO);
+}
+
+/* myhostname - figure out local machine name */
+
+static char *
+myhostname(void)
+{
+ static char name[MAXHOSTNAMELEN + 1] = "";
+
+ if (name[0] == 0) {
+ gethostname(name, sizeof(name));
+ name[MAXHOSTNAMELEN] = 0;
+ }
+ return (name);
+}
+
+/* netgroup_match - match group against machine or user */
+
+static int
+netgroup_match(const char *group, const char *machine, const char *user)
+{
+#if 0 /* original code */
+#ifdef NIS
+ static char *mydomain = 0;
+
+ if (mydomain == 0)
+ yp_get_default_domain(&mydomain);
+ return (innetgr(group, machine, user, mydomain));
+#else
+ syslog(LOG_ERR, "NIS netgroup support not configured");
+ return (NO);
+#endif
+#else /* works better with glibc? */
+ static char *mydomain = 0;
+
+ if (mydomain == 0) {
+ static char domain[MAXHOSTNAMELEN+1];
+
+ getdomainname(domain, MAXHOSTNAMELEN);
+ mydomain = domain;
+ }
+
+ return innetgr(group, machine, user, mydomain);
+#endif
+}
+
+/* user_match - match a username against one token */
+
+static int
+user_match(const char *tok, const char *string)
+{
+ struct group *group;
+#ifdef PRIMARY_GROUP_MATCH
+ struct passwd *userinf;
+#endif
+ int i;
+ char *at;
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the username, or if
+ * the token is a group that contains the username.
+ */
+
+ if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */
+ *at = 0;
+ return (user_match(tok, string) && from_match(at + 1, myhostname()));
+ } else if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match(tok + 1, (char *) 0, string));
+ } else if (string_match(tok, string)) { /* ALL or exact match */
+ return (YES);
+ } else if ((group = getgrnam(tok))) { /* try group membership */
+ for (i = 0; group->gr_mem[i]; i++)
+ if (strcasecmp(string, group->gr_mem[i]) == 0)
+ return (YES);
+#ifdef PRIMARY_GROUP_MATCH
+ /*
+ * If the sting is an user whose initial GID matches the token,
+ * accept it. May avoid excessively long lines in /etc/group.
+ * Radu-Adrian Feurdean <raf@licj.soroscj.ro>
+ *
+ * XXX - disabled by default for now. Need to verify that
+ * getpwnam() doesn't have some nasty side effects. --marekm
+ */
+ if ((userinf = getpwnam(string)))
+ if (userinf->pw_gid == group->gr_gid)
+ return (YES);
+#endif
+ }
+ return (NO);
+}
+
+static char *
+resolve_hostname(string)
+ char *string;
+{
+#if 1
+ /*
+ * Resolve hostname to numeric IP address, as suggested
+ * by Dave Hagewood <admin@arrowweb.com>. --marekm
+ */
+ struct hostent *hp;
+
+ hp = gethostbyname(string);
+ if (hp)
+ return inet_ntoa(*((struct in_addr *) *(hp->h_addr_list)));
+
+ syslog(LOG_ERR, "%s - unknown host", string);
+#endif
+ return string;
+}
+
+/* from_match - match a host or tty against a list of tokens */
+
+static int
+from_match(const char *tok, const char *string)
+{
+ int tok_len;
+ int str_len;
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds. Return
+ * YES if the token fully matches the string. If the token is a domain
+ * name, return YES if it matches the last fields of the string. If the
+ * token has the magic value "LOCAL", return YES if the string does not
+ * contain a "." character. If the token is a network number, return YES
+ * if it matches the head of the string.
+ */
+
+ if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match(tok + 1, string, (char *) 0));
+ } else if (string_match(tok, string)) { /* ALL or exact match */
+ return (YES);
+ } else if (tok[0] == '.') { /* domain: match last fields */
+ if ((str_len = strlen(string)) > (tok_len = strlen(tok))
+ && strcasecmp(tok, string + str_len - tok_len) == 0)
+ return (YES);
+ } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
+ if (strchr(string, '.') == 0)
+ return (YES);
+ } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */
+ && strncmp(tok, resolve_hostname(string), tok_len) == 0) {
+ return (YES);
+ }
+ return (NO);
+}
+
+/* string_match - match a string against one token */
+
+static int
+string_match(const char *tok, const char *string)
+{
+
+ /*
+ * If the token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the string.
+ */
+
+ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
+ return (YES);
+ } else if (strcasecmp(tok, string) == 0) { /* try exact match */
+ return (YES);
+ }
+ return (NO);
+}
+#endif /* LOGIN_ACCESS */
diff --git a/current/libmisc/login_desrpc.c b/current/libmisc/login_desrpc.c
new file mode 100644
index 00000000..9767b406
--- /dev/null
+++ b/current/libmisc/login_desrpc.c
@@ -0,0 +1,77 @@
+/* Taken from logdaemon-5.0, only minimal changes. --marekm */
+
+/************************************************************************
+* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+* may be covered by other copyrights (as noted in the file itself.)
+*
+* This material was originally written and compiled by Wietse Venema at
+* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+* 1992, 1993, 1994 and 1995.
+*
+* Redistribution and use in source and binary forms are permitted
+* provided that this entire copyright notice is duplicated in all such
+* copies.
+*
+* This software is provided "as is" and without any expressed or implied
+* warranties, including, without limitation, the implied warranties of
+* merchantibility and fitness for any particular purpose.
+************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef DES_RPC
+#include "rcsid.h"
+RCSID("$Id: login_desrpc.c,v 1.7 1999/06/07 16:40:44 marekm Exp $")
+
+#include "defines.h"
+
+ /*
+ * Decrypt the user's secret secure RPC key and stores it into the
+ * keyserver. Returns 0 if successful, -1 on failure.
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <rpc/key_prot.h>
+
+#if !(defined __GLIBC__ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)))
+/* these don't seem to be in any header file (libc-5.4.33) */
+/* but will be in glibc 2.1 <rpc/auth.h> and <rpc/auth_des.h> */
+extern int getnetname(char *);
+extern int getsecretkey(const char *, char *, const char *);
+extern int key_setsecret(const char *);
+#endif
+
+int
+login_desrpc(const char *passwd)
+{
+ char netname[MAXNETNAMELEN + 1];
+ char secretkey[HEXKEYBYTES + 1];
+
+ if (getnetname(netname) == 0)
+ return -1;
+
+ if (getsecretkey(netname, secretkey, passwd) == 0)
+ return -1;
+
+ if (secretkey[0] == 0) {
+ fprintf(stderr,
+ _("Password does not decrypt secret key for %s.\n"),
+ netname);
+ return -1;
+ }
+ if (key_setsecret(secretkey) < 0) {
+ fprintf(stderr,
+ _("Could not set %s's secret key: is the keyserv daemon running?\n"),
+ netname);
+ return -1;
+ }
+ return 0;
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif
diff --git a/current/libmisc/login_krb.c b/current/libmisc/login_krb.c
new file mode 100644
index 00000000..001a2163
--- /dev/null
+++ b/current/libmisc/login_krb.c
@@ -0,0 +1,61 @@
+/* Taken from logdaemon-5.0, only minimal changes. --marekm */
+
+/************************************************************************
+* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+* may be covered by other copyrights (as noted in the file itself.)
+*
+* This material was originally written and compiled by Wietse Venema at
+* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+* 1992, 1993, 1994 and 1995.
+*
+* Redistribution and use in source and binary forms are permitted
+* provided that this entire copyright notice is duplicated in all such
+* copies.
+*
+* This software is provided "as is" and without any expressed or implied
+* warranties, including, without limitation, the implied warranties of
+* merchantibility and fitness for any particular purpose.
+************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef KERBEROS
+#include "rcsid.h"
+RCSID("$Id: login_krb.c,v 1.3 1998/01/29 23:22:34 marekm Exp $")
+
+#include <krb.h>
+
+ /*
+ * Do an equivalent to kinit here. We need to do the kinit before trying to
+ * cd to the home directory, because it might be on a remote filesystem that
+ * uses Kerberos authentication. We also need to do this after we've
+ * setuid() to the user, or krb_get_pw_in_tkt() won't know where to put the
+ * ticket.
+ *
+ * We don't really care about whether or not it succeeds; if it fails, we'll
+ * just carry on bravely.
+ *
+ * NB: we assume: local realm, same username and password as supplied to login.
+ *
+ * Security note: if pp is NULL, login doesn't have the password. This is
+ * common when it's called by rlogind. Since this is almost always a remote
+ * connection, we don't want to risk asking for the password by supplying a
+ * NULL pp to krb_get_pw_in_tkt(), because somebody could be listening. So
+ * we'll just forget the whole thing. -jdd
+ */
+
+int
+login_kerberos(const char *username, const char *password)
+{
+ char realm[REALM_SZ];
+
+ (void) krb_get_lrealm(realm, 1);
+ if (password != 0)
+ (void) krb_get_pw_in_tkt(username, "", realm, "krbtgt",
+ realm, DEFAULT_TKT_LIFE, password);
+}
+#else
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif /* KERBEROS */
diff --git a/current/libmisc/loginprompt.c b/current/libmisc/loginprompt.c
new file mode 100644
index 00000000..abe81d3a
--- /dev/null
+++ b/current/libmisc/loginprompt.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright 1989 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: loginprompt.c,v 1.6 2000/08/26 18:27:17 marekm Exp $")
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "getdef.h"
+
+static void
+login_exit(int sig)
+{
+ exit(1);
+}
+
+/*
+ * login_prompt - prompt the user for their login name
+ *
+ * login_prompt() displays the standard login prompt. If ISSUE_FILE
+ * is set in login.defs, this file is displayed before the prompt.
+ */
+
+void
+login_prompt(const char *prompt, char *name, int namesize)
+{
+ char buf[1024];
+#define MAX_ENV 32
+ char *envp[MAX_ENV];
+ int envc;
+ char *cp;
+ int i;
+ FILE *fp;
+ RETSIGTYPE (*sigquit)(int);
+#ifdef SIGTSTP
+ RETSIGTYPE (*sigtstp)(int);
+#endif
+
+ /*
+ * There is a small chance that a QUIT character will be part of
+ * some random noise during a prompt. Deal with this by exiting
+ * instead of core dumping. If SIGTSTP is defined, do the same
+ * thing for that signal.
+ */
+
+ sigquit = signal(SIGQUIT, login_exit);
+#ifdef SIGTSTP
+ sigtstp = signal(SIGTSTP, login_exit);
+#endif
+
+ /*
+ * See if the user has configured the issue file to
+ * be displayed and display it before the prompt.
+ */
+
+ if (prompt) {
+ cp = getdef_str("ISSUE_FILE");
+ if (cp && (fp = fopen(cp, "r"))) {
+ while ((i = getc(fp)) != EOF)
+ putc(i, stdout);
+
+ fclose(fp);
+ }
+ gethostname(buf, sizeof buf);
+ printf(prompt, buf);
+ fflush(stdout);
+ }
+
+ /*
+ * Read the user's response. The trailing newline will be
+ * removed.
+ */
+
+ memzero(buf, sizeof buf);
+ if (fgets(buf, sizeof buf, stdin) != buf)
+ exit(1);
+
+ cp = strchr(buf, '\n');
+ if (!cp)
+ exit(1);
+ *cp = '\0'; /* remove \n [ must be there ] */
+
+ /*
+ * Skip leading whitespace. This makes " username" work right.
+ * Then copy the rest (up to the end or the first "non-graphic"
+ * character into the username.
+ */
+
+ for (cp = buf;*cp == ' ' || *cp == '\t';cp++)
+ ;
+
+ for (i = 0; i < namesize - 1 && isgraph(*cp); name[i++] = *cp++)
+ ;
+ while (isgraph(*cp))
+ cp++;
+
+ if (*cp)
+ cp++;
+
+ name[i] = '\0';
+
+ /*
+ * This is a disaster, at best. The user may have entered extra
+ * environmental variables at the prompt. There are several ways
+ * to do this, and I just take the easy way out.
+ */
+
+ if (*cp != '\0') { /* process new variables */
+ char *nvar;
+ int count = 1;
+
+ for (envc = 0; envc < MAX_ENV; envc++) {
+ nvar = strtok(envc ? (char *)0 : cp, " \t,");
+ if (!nvar)
+ break;
+ if (strchr(nvar, '=')) {
+ envp[envc] = nvar;
+ } else {
+ envp[envc] = xmalloc(strlen(nvar) + 32);
+ sprintf(envp[envc], "L%d=%s", count++, nvar);
+ }
+ }
+ set_env(envc, envp);
+ }
+
+ /*
+ * Set the SIGQUIT handler back to its original value
+ */
+
+ signal(SIGQUIT, sigquit);
+#ifdef SIGTSTP
+ signal(SIGTSTP, sigtstp);
+#endif
+}
diff --git a/current/libmisc/mail.c b/current/libmisc/mail.c
new file mode 100644
index 00000000..7b24e974
--- /dev/null
+++ b/current/libmisc/mail.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "getdef.h"
+
+#include "rcsid.h"
+RCSID("$Id: mail.c,v 1.7 1998/12/28 20:34:49 marekm Exp $")
+
+void
+mailcheck(void)
+{
+ struct stat statbuf;
+ char *mailbox;
+
+ if (!getdef_bool("MAIL_CHECK_ENAB"))
+ return;
+
+ /*
+ * Check incoming mail in Maildir format - J.
+ */
+ if ((mailbox = getenv("MAILDIR"))) {
+ char *newmail;
+
+ newmail = xmalloc(strlen(mailbox) + 5);
+ sprintf(newmail, "%s/new", mailbox);
+ if (stat(newmail, &statbuf) != -1 && statbuf.st_size != 0) {
+ if (statbuf.st_mtime > statbuf.st_atime) {
+ free(newmail);
+ puts(_("You have new mail."));
+ return;
+ }
+ }
+ free(newmail);
+ }
+
+ if (!(mailbox = getenv("MAIL")))
+ return;
+
+ if (stat(mailbox, &statbuf) == -1 || statbuf.st_size == 0)
+ puts(_("No mail."));
+ else if (statbuf.st_atime > statbuf.st_mtime)
+ puts(_("You have mail."));
+ else
+ puts(_("You have new mail."));
+}
+
diff --git a/current/libmisc/motd.c b/current/libmisc/motd.c
new file mode 100644
index 00000000..0ff6973e
--- /dev/null
+++ b/current/libmisc/motd.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: motd.c,v 1.3 1997/12/07 23:27:07 marekm Exp $")
+
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "getdef.h"
+
+/*
+ * motd -- output the /etc/motd file
+ *
+ * motd() determines the name of a login announcement file and outputs
+ * it to the user's terminal at login time. The MOTD_FILE configuration
+ * option is a colon-delimited list of filenames.
+ */
+
+void
+motd(void)
+{
+ FILE *fp;
+ char motdlist[BUFSIZ], *motdfile, *mb;
+ register int c;
+
+ if ((mb = getdef_str("MOTD_FILE")) == NULL)
+ return;
+
+ strncpy(motdlist, mb, sizeof(motdlist));
+ motdlist[sizeof(motdlist)-1] = '\0';
+
+ for (mb = motdlist ; (motdfile = strtok(mb,":")) != NULL ; mb = NULL) {
+ if ((fp = fopen(motdfile, "r")) != NULL) {
+ while ((c = getc (fp)) != EOF)
+ putchar (c);
+ fclose (fp);
+ }
+ }
+ fflush (stdout);
+}
diff --git a/current/libmisc/myname.c b/current/libmisc/myname.c
new file mode 100644
index 00000000..66e80e56
--- /dev/null
+++ b/current/libmisc/myname.c
@@ -0,0 +1,41 @@
+/*
+ * myname.c - determine the current username and get the passwd entry
+ *
+ * Copyright (C) 1996 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>
+ *
+ * This code may be freely used, modified and distributed for any purpose.
+ * There is no warranty, if it breaks you have to keep both pieces, etc.
+ * If you improve it, please send me your changes. Thanks!
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: myname.c,v 1.2 1997/12/07 23:27:07 marekm Exp $")
+
+#include "defines.h"
+#include <pwd.h>
+#include "prototypes.h"
+
+struct passwd *
+get_my_pwent(void)
+{
+ struct passwd *pw;
+ const char *cp = getlogin();
+ uid_t ruid = getuid();
+
+ /*
+ * Try getlogin() first - if it fails or returns a non-existent
+ * username, or a username which doesn't match the real UID, fall
+ * back to getpwuid(getuid()). This should work reasonably with
+ * usernames longer than the utmp limit (8 characters), as well as
+ * shared UIDs - but not both at the same time...
+ *
+ * XXX - when running from su, will return the current user (not
+ * the original user, like getlogin() does). Does this matter?
+ */
+ if (cp && *cp && (pw = getpwnam(cp)) && pw->pw_uid == ruid)
+ return pw;
+
+ return getpwuid(ruid);
+}
diff --git a/current/libmisc/obscure.c b/current/libmisc/obscure.c
new file mode 100644
index 00000000..845bd264
--- /dev/null
+++ b/current/libmisc/obscure.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: obscure.c,v 1.9 1999/03/07 19:14:40 marekm Exp $")
+
+/*
+ * This version of obscure.c contains modifications to support "cracklib"
+ * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib
+ * library source code for this function to operate.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include "getdef.h"
+
+/*
+ * can't be a palindrome - like `R A D A R' or `M A D A M'
+ */
+
+/*ARGSUSED*/
+static int
+palindrome(const char *old, const char *new)
+{
+ int i, j;
+
+ i = strlen (new);
+
+ for (j = 0;j < i;j++)
+ if (new[i - j - 1] != new[j])
+ return 0;
+
+ return 1;
+}
+
+/*
+ * more than half of the characters are different ones.
+ */
+
+/*ARGSUSED*/
+static int
+similar(const char *old, const char *new)
+{
+ int i, j;
+
+ /*
+ * XXX - sometimes this fails when changing from a simple password
+ * to a really long one (MD5). For now, I just return success if
+ * the new password is long enough. Please feel free to suggest
+ * something better... --marekm
+ */
+ if (strlen(new) >= 8)
+ return 0;
+
+ for (i = j = 0; new[i] && old[i]; i++)
+ if (strchr(new, old[i]))
+ j++;
+
+ if (i >= j * 2)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * a nice mix of characters.
+ */
+
+/*ARGSUSED*/
+static int
+simple(const char *old, const char *new)
+{
+ int digits = 0;
+ int uppers = 0;
+ int lowers = 0;
+ int others = 0;
+ int size;
+ int i;
+
+ for (i = 0;new[i];i++) {
+ if (isdigit (new[i]))
+ digits++;
+ else if (isupper (new[i]))
+ uppers++;
+ else if (islower (new[i]))
+ lowers++;
+ else
+ others++;
+ }
+
+ /*
+ * The scam is this - a password of only one character type
+ * must be 8 letters long. Two types, 7, and so on.
+ */
+
+ size = 9;
+ if (digits) size--;
+ if (uppers) size--;
+ if (lowers) size--;
+ if (others) size--;
+
+ if (size <= i)
+ return 0;
+
+ return 1;
+}
+
+static char *
+str_lower(char *string)
+{
+ char *cp;
+
+ for (cp = string; *cp; cp++)
+ *cp = tolower(*cp);
+ return string;
+}
+
+static const char *
+password_check(const char *old, const char *new, const struct passwd *pwdp)
+{
+ const char *msg = NULL;
+ char *oldmono, *newmono, *wrapped;
+#ifdef HAVE_LIBCRACK
+ char *dictpath;
+#ifdef HAVE_LIBCRACK_PW
+ char *FascistCheckPw();
+#else
+ char *FascistCheck();
+#endif
+#endif
+
+ if (strcmp(new, old) == 0)
+ return "no change";
+
+ newmono = str_lower(xstrdup(new));
+ oldmono = str_lower(xstrdup(old));
+ wrapped = xmalloc(strlen(oldmono) * 2 + 1);
+ strcpy (wrapped, oldmono);
+ strcat (wrapped, oldmono);
+
+ if (palindrome(oldmono, newmono))
+ msg = "a palindrome";
+
+ if (!msg && strcmp(oldmono, newmono) == 0)
+ msg = "case changes only";
+
+ if (!msg && similar(oldmono, newmono))
+ msg = "too similar";
+
+ if (!msg && simple(old, new))
+ msg = "too simple";
+
+ if (!msg && strstr(wrapped, newmono))
+ msg = "rotated";
+
+#ifdef HAVE_LIBCRACK
+ /*
+ * Invoke Alec Muffett's cracklib routines.
+ */
+
+ if (!msg && (dictpath = getdef_str("CRACKLIB_DICTPATH")))
+#ifdef HAVE_LIBCRACK_PW
+ msg = FascistCheckPw(new, dictpath, pwdp);
+#else
+ msg = FascistCheck(new, dictpath);
+#endif
+#endif
+ strzero(newmono);
+ strzero(oldmono);
+ strzero(wrapped);
+ free(newmono);
+ free(oldmono);
+ free(wrapped);
+
+ return msg;
+}
+
+/*ARGSUSED*/
+static const char *
+obscure_msg(const char *old, const char *new, const struct passwd *pwdp)
+{
+ int maxlen, oldlen, newlen;
+ char *new1, *old1;
+ const char *msg;
+
+ oldlen = strlen(old);
+ newlen = strlen(new);
+
+#if 0 /* why not check the password when set for the first time? --marekm */
+ if (old[0] == '\0')
+ return NULL;
+#endif
+
+ if ( newlen < getdef_num("PASS_MIN_LEN", 0) )
+ return "too short";
+
+ /*
+ * Remaining checks are optional.
+ */
+ if (!getdef_bool("OBSCURE_CHECKS_ENAB"))
+ return NULL;
+
+ msg = password_check(old, new, pwdp);
+ if (msg)
+ return msg;
+
+ /* The traditional crypt() truncates passwords to 8 chars. It is
+ possible to circumvent the above checks by choosing an easy
+ 8-char password and adding some random characters to it...
+ Example: "password$%^&*123". So check it again, this time
+ truncated to the maximum length. Idea from npasswd. --marekm */
+
+ if (getdef_bool("MD5_CRYPT_ENAB"))
+ return NULL; /* unlimited password length */
+
+ maxlen = getdef_num("PASS_MAX_LEN", 8);
+ if (oldlen <= maxlen && newlen <= maxlen)
+ return NULL;
+
+ new1 = xstrdup(new);
+ old1 = xstrdup(old);
+ if (newlen > maxlen)
+ new1[maxlen] = '\0';
+ if (oldlen > maxlen)
+ old1[maxlen] = '\0';
+
+ msg = password_check(old1, new1, pwdp);
+
+ memzero(new1, newlen);
+ memzero(old1, oldlen);
+ free(new1);
+ free(old1);
+
+ return msg;
+}
+
+/*
+ * Obscure - see if password is obscure enough.
+ *
+ * The programmer is encouraged to add as much complexity to this
+ * routine as desired. Included are some of my favorite ways to
+ * check passwords.
+ */
+
+int
+obscure(const char *old, const char *new, const struct passwd *pwdp)
+{
+ const char *msg = obscure_msg(old, new, pwdp);
+ if (msg) {
+ printf(_("Bad password: %s. "), msg);
+ return 0;
+ }
+ return 1;
+}
+
diff --git a/current/libmisc/pam_pass.c b/current/libmisc/pam_pass.c
new file mode 100644
index 00000000..b3e7ac75
--- /dev/null
+++ b/current/libmisc/pam_pass.c
@@ -0,0 +1,58 @@
+#include <config.h>
+
+#ifdef USE_PAM
+
+#include "rcsid.h"
+RCSID("$Id: pam_pass.c,v 1.6 1999/06/07 16:40:44 marekm Exp $")
+
+/*
+ * Change the user's password using PAM. Requires libpam and libpam_misc
+ * (for misc_conv). Note: libpam_misc is probably Linux-PAM specific,
+ * so you may have to port it if you want to use this code on non-Linux
+ * systems with PAM (such as Solaris 2.6). --marekm
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "defines.h"
+
+#include "pam_defs.h"
+
+static const struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+void
+do_pam_passwd(const char *user, int silent, int change_expired)
+{
+ pam_handle_t *pamh = NULL;
+ int flags = 0, ret;
+
+ if (silent)
+ flags |= PAM_SILENT;
+ if (change_expired)
+ flags |= PAM_CHANGE_EXPIRED_AUTHTOK;
+
+ ret = pam_start("passwd", user, &conv, &pamh);
+ if (ret != PAM_SUCCESS) {
+ fprintf(stderr, _("passwd: pam_start() failed, error %d\n"),
+ ret);
+ exit(10); /* XXX */
+ }
+
+ ret = pam_chauthtok(pamh, flags);
+ if (ret != PAM_SUCCESS) {
+ fprintf(stderr, _("passwd: %s\n"), PAM_STRERROR(pamh, ret));
+ pam_end(pamh, ret);
+ exit(10); /* XXX */
+ }
+
+ pam_end(pamh, PAM_SUCCESS);
+}
+#else /* !USE_PAM */
+extern int errno; /* warning: ANSI C forbids an empty source file */
+#endif /* !USE_PAM */
diff --git a/current/libmisc/pwd2spwd.c b/current/libmisc/pwd2spwd.c
new file mode 100644
index 00000000..e53d96ab
--- /dev/null
+++ b/current/libmisc/pwd2spwd.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef SHADOWPWD
+
+#include "rcsid.h"
+RCSID("$Id: pwd2spwd.c,v 1.3 1997/12/07 23:27:07 marekm Exp $")
+
+#include <sys/types.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+
+extern time_t time ();
+
+/*
+ * pwd_to_spwd - create entries for new spwd structure
+ *
+ * pwd_to_spwd() creates a new (struct spwd) containing the
+ * information in the pointed-to (struct passwd).
+ */
+
+struct spwd *
+pwd_to_spwd(const struct passwd *pw)
+{
+ static struct spwd sp;
+
+ /*
+ * Nice, easy parts first. The name and passwd map directly
+ * from the old password structure to the new one.
+ */
+ sp.sp_namp = pw->pw_name;
+ sp.sp_pwdp = pw->pw_passwd;
+
+#ifdef ATT_AGE
+ /*
+ * AT&T-style password aging maps the sp_min, sp_max, and
+ * sp_lstchg information from the pw_age field, which appears
+ * after the encrypted password.
+ */
+ if (pw->pw_age[0]) {
+ sp.sp_max = (c64i(pw->pw_age[0]) * WEEK) / SCALE;
+
+ if (pw->pw_age[1])
+ sp.sp_min = (c64i(pw->pw_age[1]) * WEEK) / SCALE;
+ else
+ sp.sp_min = (10000L * DAY) / SCALE;
+
+ if (pw->pw_age[1] && pw->pw_age[2])
+ sp.sp_lstchg = (a64l(pw->pw_age + 2) * WEEK) / SCALE;
+ else
+ sp.sp_lstchg = time((time_t *) 0) / SCALE;
+ } else
+#endif
+ {
+ /*
+ * Defaults used if there is no pw_age information.
+ */
+ sp.sp_min = 0;
+ sp.sp_max = (10000L * DAY) / SCALE;
+ sp.sp_lstchg = time((time_t *) 0) / SCALE;
+ }
+
+ /*
+ * These fields have no corresponding information in the password
+ * file. They are set to uninitialized values.
+ */
+ sp.sp_warn = -1;
+ sp.sp_expire = -1;
+ sp.sp_inact = -1;
+ sp.sp_flag = -1;
+
+ return &sp;
+}
+#endif /* SHADOWPWD */
diff --git a/current/libmisc/pwd_init.c b/current/libmisc/pwd_init.c
new file mode 100644
index 00000000..e09f02bd
--- /dev/null
+++ b/current/libmisc/pwd_init.c
@@ -0,0 +1,73 @@
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: pwd_init.c,v 1.1 1997/12/07 23:27:07 marekm Exp $")
+
+#include "defines.h"
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+/*
+ * pwd_init - ignore signals, and set resource limits to safe
+ * values. Call this before modifying password files, so that
+ * it is less likely to fail in the middle of operation.
+ */
+void
+pwd_init(void)
+{
+#ifdef HAVE_SYS_RESOURCE_H
+ struct rlimit rlim;
+
+#ifdef RLIMIT_CORE
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+#endif
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+#ifdef RLIMIT_AS
+ setrlimit(RLIMIT_AS, &rlim);
+#endif
+#ifdef RLIMIT_CPU
+ setrlimit(RLIMIT_CPU, &rlim);
+#endif
+#ifdef RLIMIT_DATA
+ setrlimit(RLIMIT_DATA, &rlim);
+#endif
+#ifdef RLIMIT_FSIZE
+ setrlimit(RLIMIT_FSIZE, &rlim);
+#endif
+#ifdef RLIMIT_NOFILE
+ setrlimit(RLIMIT_NOFILE, &rlim);
+#endif
+#ifdef RLIMIT_RSS
+ setrlimit(RLIMIT_RSS, &rlim);
+#endif
+#ifdef RLIMIT_STACK
+ setrlimit(RLIMIT_STACK, &rlim);
+#endif
+#else /* !HAVE_SYS_RESOURCE_H */
+ set_filesize_limit(30000);
+ /* don't know how to set the other limits... */
+#endif /* !HAVE_SYS_RESOURCE_H */
+
+ signal(SIGALRM, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
+#ifdef SIGTSTP
+ signal(SIGTSTP, SIG_IGN);
+#endif
+#ifdef SIGTTOU
+ signal(SIGTTOU, SIG_IGN);
+#endif
+
+ umask(077);
+}
+
diff --git a/current/libmisc/pwdcheck.c b/current/libmisc/pwdcheck.c
new file mode 100644
index 00000000..1b3cea74
--- /dev/null
+++ b/current/libmisc/pwdcheck.c
@@ -0,0 +1,69 @@
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id$")
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include <pwd.h>
+#include "pwauth.h"
+
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+#ifdef USE_PAM
+#include "pam_defs.h"
+#endif
+
+#define WRONGPWD2 "incorrect password for `%s'"
+
+void
+passwd_check(const char *user, const char *passwd, const char *progname)
+{
+#ifdef USE_PAM
+ pam_handle_t *pamh = NULL;
+ int retcode;
+ struct pam_conv conv = { misc_conv, NULL };
+
+ if (pam_start(progname, user, &conv, &pamh)) {
+bailout:
+ SYSLOG((LOG_WARN, WRONGPWD2, user));
+ sleep(1);
+ fprintf(stderr, _("Incorrect password for %s.\n"), user);
+ exit(1);
+ }
+ if (pam_authenticate(pamh, 0))
+ goto bailout;
+
+ retcode = pam_acct_mgmt(pamh, 0);
+ if (retcode == PAM_NEW_AUTHTOK_REQD) {
+ retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ } else if (retcode)
+ goto bailout;
+
+ if (pam_setcred(pamh, 0))
+ goto bailout;
+
+ /* no need to establish a session; this isn't a session-oriented
+ * activity... */
+
+#else /* !USE_PAM */
+
+#ifdef SHADOWPWD
+ struct spwd *sp;
+
+ if ((sp = getspnam(user)))
+ passwd = sp->sp_pwdp;
+ endspent();
+#endif
+ if (pw_auth(passwd, user, PW_LOGIN, (char *) 0) != 0) {
+ SYSLOG((LOG_WARN, WRONGPWD2, user));
+ sleep(1);
+ fprintf(stderr, _("Incorrect password for %s.\n"), user);
+ exit(1);
+ }
+#endif /* !USE_PAM */
+}
+
diff --git a/current/libmisc/rlogin.c b/current/libmisc/rlogin.c
new file mode 100644
index 00000000..d79cc1d9
--- /dev/null
+++ b/current/libmisc/rlogin.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef RLOGIN
+
+#include "rcsid.h"
+RCSID("$Id: rlogin.c,v 1.5 1999/08/27 19:02:51 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include <stdio.h>
+#include <pwd.h>
+
+extern int ruserok();
+
+static struct {
+ int spd_name;
+ int spd_baud;
+} speed_table [] = {
+#ifdef B50
+ { B50, 50 },
+#endif
+#ifdef B75
+ { B75, 75 },
+#endif
+#ifdef B110
+ { B110, 110 },
+#endif
+#ifdef B134
+ { B134, 134 },
+#endif
+#ifdef B150
+ { B150, 150 },
+#endif
+#ifdef B200
+ { B200, 200 },
+#endif
+#ifdef B300
+ { B300, 300 },
+#endif
+#ifdef B600
+ { B600, 600 },
+#endif
+#ifdef B1200
+ { B1200, 1200 },
+#endif
+#ifdef B1800
+ { B1800, 1800 },
+#endif
+#ifdef B2400
+ { B2400, 2400 },
+#endif
+#ifdef B4800
+ { B4800, 4800 },
+#endif
+#ifdef B9600
+ { B9600, 9600 },
+#endif
+#ifdef B19200
+ { B19200, 19200 },
+#endif
+#ifdef B38400
+ { B38400, 38400 },
+#endif
+ { -1, -1 }
+};
+
+static void
+get_remote_string(char *buf, int size)
+{
+ for (;;) {
+ if (read (0, buf, 1) != 1)
+ exit (1);
+ if (*buf == '\0')
+ return;
+ if (--size > 0)
+ ++buf;
+ }
+ /*NOTREACHED*/
+}
+
+int
+do_rlogin(const char *remote_host, char *name, int namelen, char *term, int termlen)
+{
+ struct passwd *pwd;
+ char remote_name[32];
+ char *cp;
+ int remote_speed = 9600;
+ int speed_name = B9600;
+ int i;
+ TERMIO termio;
+
+ get_remote_string (remote_name, sizeof remote_name);
+ get_remote_string (name, namelen);
+ get_remote_string (term, termlen);
+
+ if ((cp = strchr (term, '/'))) {
+ *cp++ = '\0';
+
+ if (! (remote_speed = atoi (cp)))
+ remote_speed = 9600;
+ }
+ for (i = 0;speed_table[i].spd_baud != remote_speed &&
+ speed_table[i].spd_name != -1;i++)
+ ;
+
+ if (speed_table[i].spd_name != -1)
+ speed_name = speed_table[i].spd_name;
+
+ /*
+ * Put the terminal in cooked mode with echo turned on.
+ */
+
+ GTTY(0, &termio);
+ termio.c_iflag |= ICRNL|IXON;
+ termio.c_oflag |= OPOST|ONLCR;
+ termio.c_lflag |= ICANON|ECHO|ECHOE;
+#ifdef CBAUD
+ termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
+#else
+ termio.c_cflag = (termio.c_cflag) | speed_name;
+#endif
+ STTY(0, &termio);
+
+ if (! (pwd = getpwnam (name)))
+ return 0;
+
+ /*
+ * ruserok() returns 0 for success on modern systems, and 1 on
+ * older ones. If you are having trouble with people logging
+ * in without giving a required password, THIS is the culprit -
+ * go fix the #define in config.h.
+ */
+
+#ifndef RUSEROK
+ return 0;
+#else
+ return ruserok (remote_host, pwd->pw_uid == 0,
+ remote_name, name) == RUSEROK;
+#endif
+}
+#endif /* RLOGIN */
diff --git a/current/libmisc/salt.c b/current/libmisc/salt.c
new file mode 100644
index 00000000..b5478e45
--- /dev/null
+++ b/current/libmisc/salt.c
@@ -0,0 +1,70 @@
+/*
+ * salt.c - generate a random salt string for crypt()
+ *
+ * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
+ * public domain.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: salt.c,v 1.5 1997/12/07 23:27:09 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include <sys/time.h>
+
+#if 1
+#include "getdef.h"
+
+extern char *l64a();
+
+/*
+ * Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
+ * in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
+ * (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
+ * version of crypt() instead of the standard one.
+ */
+char *
+crypt_make_salt(void)
+{
+ struct timeval tv;
+ static char result[40];
+
+ result[0] = '\0';
+ if (getdef_bool("MD5_CRYPT_ENAB")) {
+ strcpy(result, "$1$"); /* magic for the new MD5 crypt() */
+ }
+
+ /*
+ * Generate 8 chars of salt, the old crypt() will use only first 2.
+ */
+ gettimeofday(&tv, (struct timezone *) 0);
+ strcat(result, l64a(tv.tv_usec));
+ strcat(result, l64a(tv.tv_sec + getpid() + clock()));
+
+ if (strlen(result) > 3 + 8) /* magic+salt */
+ result[11] = '\0';
+
+ return result;
+}
+#else
+
+/*
+ * This is the old style random salt generator...
+ */
+char *
+crypt_make_salt(void)
+{
+ time_t now;
+ static unsigned long x;
+ static char result[3];
+
+ time(&now);
+ x += now + getpid() + clock();
+ result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
+ result[1] = i64c(((x >> 12) ^ x) & 077);
+ result[2] = '\0';
+ return result;
+}
+#endif
diff --git a/current/libmisc/setugid.c b/current/libmisc/setugid.c
new file mode 100644
index 00000000..5dae7659
--- /dev/null
+++ b/current/libmisc/setugid.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Separated from setup.c. --marekm
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: setugid.c,v 1.6 1998/07/23 22:13:16 marekm Exp $")
+
+#include <stdio.h>
+#include <grp.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+
+#include "getdef.h"
+
+/*
+ * setup_uid_gid() split in two functions for PAM support -
+ * pam_setcred() needs to be called after initgroups(), but
+ * before setuid().
+ */
+
+int
+setup_groups(const struct passwd *info)
+{
+ /*
+ * Set the real group ID to the primary group ID in the password
+ * file.
+ */
+ if (setgid (info->pw_gid) == -1) {
+ perror("setgid");
+ SYSLOG((LOG_ERR, "bad group ID `%d' for user `%s': %m\n",
+ info->pw_gid, info->pw_name));
+ closelog();
+ return -1;
+ }
+#ifdef HAVE_INITGROUPS
+ /*
+ * For systems which support multiple concurrent groups, go get
+ * the group set from the /etc/group file.
+ */
+ if (initgroups(info->pw_name, info->pw_gid) == -1) {
+ perror("initgroups");
+ SYSLOG((LOG_ERR, "initgroups failed for user `%s': %m\n",
+ info->pw_name));
+ closelog();
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+int
+change_uid(const struct passwd *info)
+{
+ /*
+ * Set the real UID to the UID value in the password file.
+ */
+#ifndef BSD
+ if (setuid(info->pw_uid))
+#else
+ if (setreuid(info->pw_uid, info->pw_uid))
+#endif
+ {
+ perror("setuid");
+ SYSLOG((LOG_ERR, "bad user ID `%d' for user `%s': %m\n",
+ (int) info->pw_uid, info->pw_name));
+ closelog();
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * setup_uid_gid() performs the following steps -
+ *
+ * set the group ID to the value from the password file entry
+ * set the supplementary group IDs
+ * optionally call specified function which may add more groups
+ * set the user ID to the value from the password file entry
+ *
+ * Returns 0 on success, or -1 on failure.
+ */
+
+int
+setup_uid_gid(const struct passwd *info, int is_console)
+{
+ if (setup_groups(info) < 0)
+ return -1;
+
+#ifdef HAVE_INITGROUPS
+ if (is_console) {
+ char *cp = getdef_str("CONSOLE_GROUPS");
+ if (cp && add_groups(cp))
+ perror("Warning: add_groups");
+ }
+#endif /* HAVE_INITGROUPS */
+
+ if (change_uid(info) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/current/libmisc/setup.c b/current/libmisc/setup.c
new file mode 100644
index 00000000..7b8df91b
--- /dev/null
+++ b/current/libmisc/setup.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: setup.c,v 1.3 1997/12/07 23:27:09 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+
+/*
+ * setup - initialize login environment
+ *
+ * setup() performs the following steps -
+ *
+ * set the process nice, ulimit, and umask from the password file entry
+ * set the group ID to the value from the password file entry
+ * set the supplementary group IDs
+ * set the user ID to the value from the password file entry
+ * change to the user's home directory
+ * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
+ * variables.
+ */
+
+void
+setup(struct passwd *info)
+{
+ /*
+ * Set resource limits.
+ */
+ setup_limits(info);
+
+ /*
+ * Set the real group ID, do initgroups, and set the real user ID
+ * to the value in the password file.
+ */
+ if (setup_uid_gid(info, 0))
+ exit(1);
+
+ /*
+ * Change to the home directory, and set up environment.
+ */
+ setup_env(info);
+}
diff --git a/current/libmisc/setupenv.c b/current/libmisc/setupenv.c
new file mode 100644
index 00000000..1e428ba7
--- /dev/null
+++ b/current/libmisc/setupenv.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Separated from setup.c. --marekm
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: setupenv.c,v 1.10 2000/08/26 18:27:17 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include "getdef.h"
+
+static void
+addenv_path(const char *varname, const char *dirname, const char *filename)
+{
+ char *buf;
+
+ buf = xmalloc(strlen(dirname) + strlen(filename) + 2);
+ sprintf(buf, "%s/%s", dirname, filename);
+ addenv(varname, buf);
+ free(buf);
+}
+
+
+static void
+read_env_file(const char *filename)
+{
+ FILE *fp;
+ char buf[1024];
+ char *cp, *name, *val;
+
+ fp = fopen(filename, "r");
+ if (!fp)
+ return;
+ while (fgets(buf, sizeof buf, fp) == buf) {
+ cp = strrchr(buf, '\n');
+ if (!cp)
+ break;
+ *cp = '\0';
+
+ cp = buf;
+ /* ignore whitespace and comments */
+ while (*cp && isspace(*cp))
+ cp++;
+ if (*cp == '\0' || *cp == '#')
+ continue;
+ /*
+ * ignore lines which don't follow the name=value format
+ * (for example, the "export NAME" shell commands)
+ */
+ name = cp;
+ while (*cp && !isspace(*cp) && *cp != '=')
+ cp++;
+ if (*cp != '=')
+ continue;
+ /* NUL-terminate the name */
+ *cp++ = '\0';
+ val = cp;
+#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
+/*
+ (state, char_type) -> (state, action)
+
+ state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped
+ char_type: normal, white, backslash, single, double
+ action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX
+*/
+no_quote:
+ if (*cp == '\\') {
+ /* remove the backslash */
+ remove_char(cp);
+ /* skip over the next character */
+ if (*cp)
+ cp++;
+ goto no_quote;
+ } else if (*cp == '\'') {
+ /* remove the quote */
+ remove_char(cp);
+ /* now within single quotes */
+ goto s_quote;
+ } else if (*cp == '"') {
+ /* remove the quote */
+ remove_char(cp);
+ /* now within double quotes */
+ goto d_quote;
+ } else if (*cp == '\0') {
+ /* end of string */
+ goto finished;
+ } else if (isspace(*cp)) {
+ /* unescaped whitespace - end of string */
+ *cp = '\0';
+ goto finished;
+ } else {
+ cp++;
+ goto no_quote;
+ }
+s_quote:
+ if (*cp == '\'') {
+ /* remove the quote */
+ remove_char(cp);
+ /* unquoted again */
+ goto no_quote;
+ } else if (*cp == '\0') {
+ /* end of string */
+ goto finished;
+ } else {
+ /* preserve everything within single quotes */
+ cp++;
+ goto s_quote;
+ }
+d_quote:
+ if (*cp == '\"') {
+ /* remove the quote */
+ remove_char(cp);
+ /* unquoted again */
+ goto no_quote;
+ } else if (*cp == '\\') {
+ cp++;
+ /* if backslash followed by double quote, remove backslash
+ else skip over the backslash and following char */
+ if (*cp == '"')
+ remove_char(cp - 1);
+ else if (*cp)
+ cp++;
+ goto d_quote;
+ } eise if (*cp == '\0') {
+ /* end of string */
+ goto finished;
+ } else {
+ /* preserve everything within double quotes */
+ goto d_quote;
+ }
+finished:
+#endif /* 0 */
+ /*
+ * XXX - should handle quotes, backslash escapes, etc.
+ * like the shell does.
+ */
+ addenv(name, val);
+ }
+ fclose(fp);
+}
+
+/*
+ * change to the user's home directory
+ * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
+ * variables.
+ */
+
+void
+setup_env(struct passwd *info)
+{
+ char *cp, *envf;
+
+ /*
+ * Change the current working directory to be the home directory
+ * of the user. It is a fatal error for this process to be unable
+ * to change to that directory. There is no "default" home
+ * directory.
+ *
+ * We no longer do it as root - should work better on NFS-mounted
+ * home directories. Some systems default to HOME=/, so we make
+ * this a configurable option. --marekm
+ */
+
+ if (chdir(info->pw_dir) == -1) {
+ static char temp_pw_dir[] = "/";
+ if (!getdef_bool("DEFAULT_HOME") || chdir("/") == -1) {
+ fprintf(stderr, _("Unable to cd to \"%s\"\n"),
+ info->pw_dir);
+ SYSLOG((LOG_WARN,
+ "unable to cd to `%s' for user `%s'\n",
+ info->pw_dir, info->pw_name));
+ closelog();
+ exit (1);
+ }
+ puts(_("No directory, logging in with HOME=/"));
+ info->pw_dir = temp_pw_dir;
+ }
+
+ /*
+ * Create the HOME environmental variable and export it.
+ */
+
+ addenv("HOME", info->pw_dir);
+
+ /*
+ * Create the SHELL environmental variable and export it.
+ */
+
+ if (info->pw_shell == (char *) 0 || ! *info->pw_shell) {
+ static char temp_pw_shell[] = "/bin/sh";
+ info->pw_shell = temp_pw_shell;
+ }
+
+ addenv("SHELL", info->pw_shell);
+
+ /*
+ * Create the PATH environmental variable and export it.
+ */
+
+ cp = getdef_str((info->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
+#if 0
+ addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL);
+#else
+ if (!cp) {
+ /* not specified, use a minimal default */
+ addenv("PATH=/bin:/usr/bin", NULL);
+ } else if (strchr(cp, '=')) {
+ /* specified as name=value (PATH=...) */
+ addenv(cp, NULL);
+ } else {
+ /* only value specified without "PATH=" */
+ addenv("PATH", cp);
+ }
+#endif
+
+ /*
+ * Export the user name. For BSD derived systems, it's "USER", for
+ * all others it's "LOGNAME". We set both of them.
+ */
+
+ addenv("USER", info->pw_name);
+ addenv("LOGNAME", info->pw_name);
+
+ /*
+ * MAILDIR environment variable for Qmail
+ */
+ if ((cp=getdef_str("QMAIL_DIR")))
+ addenv_path("MAILDIR", info->pw_dir, cp);
+
+ /*
+ * Create the MAIL environmental variable and export it. login.defs
+ * knows the prefix.
+ */
+
+ if ((cp=getdef_str("MAIL_DIR")))
+ addenv_path("MAIL", cp, info->pw_name);
+ else if ((cp=getdef_str("MAIL_FILE")))
+ addenv_path("MAIL", info->pw_dir, cp);
+ else {
+#if defined(MAIL_SPOOL_FILE)
+ addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
+#elif defined(MAIL_SPOOL_DIR)
+ addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name);
+#endif
+ }
+
+#ifndef USE_PAM
+ /*
+ * Read environment from optional config file. --marekm
+ */
+ if ((envf = getdef_str("ENVIRON_FILE")))
+ read_env_file(envf);
+#endif
+}
diff --git a/current/libmisc/shell.c b/current/libmisc/shell.c
new file mode 100644
index 00000000..23058f37
--- /dev/null
+++ b/current/libmisc/shell.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: shell.c,v 1.7 1998/12/28 20:34:53 marekm Exp $")
+
+#include <stdio.h>
+#include <errno.h>
+#include "prototypes.h"
+#include "defines.h"
+
+
+extern char **newenvp;
+extern size_t newenvc;
+
+/*
+ * shell - execute the named program
+ *
+ * shell begins by trying to figure out what argv[0] is going to
+ * be for the named process. The user may pass in that argument,
+ * or it will be the last pathname component of the file with a
+ * '-' prepended. The first attempt is to just execute the named
+ * file. If the errno comes back "ENOEXEC", the file is assumed
+ * at first glance to be a shell script. The first two characters
+ * must be "#!", in which case "/bin/sh" is executed to process
+ * the file. If all that fails, give up in disgust ...
+ */
+
+void
+shell(const char *file, const char *arg)
+{
+ char arg0[1024];
+ int err;
+
+ if (file == (char *) 0)
+ exit (1);
+
+ /*
+ * The argv[0]'th entry is usually the path name, but
+ * for various reasons the invoker may want to override
+ * that. So, we determine the 0'th entry only if they
+ * don't want to tell us what it is themselves.
+ */
+
+ if (arg == (char *) 0) {
+ snprintf(arg0, sizeof arg0, "-%s", Basename((char *) file));
+ arg = arg0;
+ }
+#ifdef DEBUG
+ printf (_("Executing shell %s\n"), file);
+#endif
+
+ /*
+ * First we try the direct approach. The system should be
+ * able to figure out what we are up to without too much
+ * grief.
+ */
+
+ execle (file, arg, (char *) 0, newenvp);
+ err = errno;
+
+ /* Linux handles #! in the kernel, and bash doesn't make
+ sense of "#!" so it wouldn't work anyway... --marekm */
+#ifndef __linux__
+ /*
+ * It is perfectly OK to have a shell script for a login
+ * shell, and this code attempts to support that. It
+ * relies on the standard shell being able to make sense
+ * of the "#!" magic number.
+ */
+
+ if (err == ENOEXEC) {
+ FILE *fp;
+
+ if ((fp = fopen (file, "r"))) {
+ if (getc (fp) == '#' && getc (fp) == '!') {
+ fclose (fp);
+ execle ("/bin/sh", "sh",
+ file, (char *) 0, newenvp);
+ err = errno;
+ } else {
+ fclose (fp);
+ }
+ }
+ }
+#endif
+
+ /*
+ * Obviously something is really wrong - I can't figure out
+ * how to execute this stupid shell, so I might as well give
+ * up in disgust ...
+ */
+
+ snprintf(arg0, sizeof arg0, _("Cannot execute %s"), file);
+ errno = err;
+ perror(arg0);
+ exit(1);
+}
diff --git a/current/libmisc/strtoday.c b/current/libmisc/strtoday.c
new file mode 100644
index 00000000..4870f9df
--- /dev/null
+++ b/current/libmisc/strtoday.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(__GLIBC__)
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: strtoday.c,v 1.8 1999/03/07 19:14:42 marekm Exp $")
+
+#include "defines.h"
+
+#ifndef USE_GETDATE
+#define USE_GETDATE 1
+#endif
+
+#if USE_GETDATE
+
+#include "getdate.h"
+
+/*
+ * strtoday() now uses get_date() (borrowed from GNU shellutils)
+ * which can handle many date formats, for example:
+ * 1970-09-17 # ISO 8601.
+ * 70-9-17 # This century assumed by default.
+ * 70-09-17 # Leading zeros are ignored.
+ * 9/17/72 # Common U.S. writing.
+ * 24 September 1972
+ * 24 Sept 72 # September has a special abbreviation.
+ * 24 Sep 72 # Three-letter abbreviations always allowed.
+ * Sep 24, 1972
+ * 24-sep-72
+ * 24sep72
+ */
+long
+strtoday(const char *str)
+{
+ time_t t;
+
+ /*
+ * get_date() interprets an empty string as the current date,
+ * which is not what we expect, unless you're a BOFH :-).
+ * (useradd sets sp_expire = current date for new lusers)
+ */
+ if (!str || *str == '\0')
+ return -1;
+
+ t = get_date(str, (time_t *) 0);
+ if (t == (time_t) -1)
+ return -1;
+ /* convert seconds to days since 1970-01-01 */
+ return (t + DAY/2)/DAY;
+}
+
+#else /* !USE_GETDATE */
+/*
+ * Old code, just in case get_date() doesn't work as expected...
+ */
+
+#include <stdio.h>
+
+#ifdef HAVE_STRPTIME
+/*
+ * for now we allow just one format, but we can define more later
+ * (we try them all until one succeeds). --marekm
+ */
+static char *date_formats[] = {
+ "%Y-%m-%d",
+ (char *) 0
+};
+#else
+/*
+ * days and juldays are used to compute the number of days in the
+ * current month, and the cummulative number of days in the preceding
+ * months. they are declared so that january is 1, not 0.
+ */
+
+static short days[13] = { 0,
+ 31, 28, 31, 30, 31, 30, /* JAN - JUN */
+ 31, 31, 30, 31, 30, 31 }; /* JUL - DEC */
+
+static short juldays[13] = { 0,
+ 0, 31, 59, 90, 120, 151, /* JAN - JUN */
+ 181, 212, 243, 273, 304, 334 }; /* JUL - DEC */
+#endif
+
+/*
+ * strtoday - compute the number of days since 1970.
+ *
+ * the total number of days prior to the current date is
+ * computed. january 1, 1970 is used as the origin with
+ * it having a day number of 0.
+ */
+
+long
+strtoday(const char *str)
+{
+#ifdef HAVE_STRPTIME
+ struct tm tp;
+ char * const *fmt;
+ char *cp;
+ time_t result;
+
+ memzero(&tp, sizeof tp);
+ for (fmt = date_formats; *fmt; fmt++) {
+ cp = strptime((char *) str, *fmt, &tp);
+ if (!cp || *cp != '\0')
+ continue;
+
+ result = mktime(&tp);
+ if (result == (time_t) -1)
+ continue;
+
+ return result / DAY; /* success */
+ }
+ return -1;
+#else
+ char slop[2];
+ int month;
+ int day;
+ int year;
+ long total;
+
+ /*
+ * start by separating the month, day and year. the order
+ * is compiled in ...
+ */
+
+ if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3)
+ return -1;
+
+ /*
+ * the month, day of the month, and year are checked for
+ * correctness and the year adjusted so it falls between
+ * 1970 and 2069.
+ */
+
+ if (month < 1 || month > 12)
+ return -1;
+
+ if (day < 1)
+ return -1;
+
+ if ((month != 2 || (year % 4) != 0) && day > days[month])
+ return -1;
+ else if ((month == 2 && (year % 4) == 0) && day > 29)
+ return -1;
+
+ if (year < 0)
+ return -1;
+ else if (year <= 69)
+ year += 2000;
+ else if (year <= 99)
+ year += 1900;
+
+ /*
+ * On systems with 32-bit signed time_t, time wraps around in 2038
+ * - for now we just limit the year to 2037 (instead of 2069).
+ * This limit can be removed once no one is using 32-bit systems
+ * anymore :-). --marekm
+ */
+ if (year < 1970 || year > 2037)
+ return -1;
+
+ /*
+ * the total number of days is the total number of days in all
+ * the whole years, plus the number of leap days, plus the
+ * number of days in the whole months preceding, plus the number
+ * of days so far in the month.
+ */
+
+ total = (long) ((year - 1970) * 365L) + (((year + 1) - 1970) / 4);
+ total += (long) juldays[month] + (month > 2 && (year % 4) == 0 ? 1:0);
+ total += (long) day - 1;
+
+ return total;
+#endif /* HAVE_STRPTIME */
+}
+#endif /* !USE_GETDATE */
diff --git a/current/libmisc/suauth.c b/current/libmisc/suauth.c
new file mode 100644
index 00000000..77cf9292
--- /dev/null
+++ b/current/libmisc/suauth.c
@@ -0,0 +1,201 @@
+#include <config.h>
+
+#ifdef SU_ACCESS
+
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <errno.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#ifndef SUAUTHFILE
+#define SUAUTHFILE "/etc/suauth"
+#endif
+
+#define NOACTION 0
+#define NOPWORD 1
+#define DENY -1
+#define OWNPWORD 2
+
+/* Really, I could do with a few const char's here defining all the
+ * strings output to the user or the syslog. -- chris
+ */
+
+static int applies(const char *, char *);
+
+int check_su_auth(const char *, const char *);
+int isgrp(const char *, const char *);
+
+static int lines = 0;
+
+extern struct passwd pwent;
+
+int
+check_su_auth(const char *actual_id, const char *wanted_id)
+{
+ int posn, endline;
+ const char field[] = ":";
+ FILE *authfile_fd;
+ char temp[1024];
+ char *to_users;
+ char *from_users;
+ char *action;
+
+ if (!(authfile_fd = fopen(SUAUTHFILE, "r"))) {
+ /*
+ * If the file doesn't exist - default to the standard su
+ * behaviour (no access control). If open fails for some
+ * other reason - maybe someone is trying to fool us with
+ * file descriptors limit etc., so deny access. --marekm
+ */
+ if (errno == ENOENT)
+ return NOACTION;
+ SYSLOG((LOG_ERR, "could not open/read config file '%s': %m\n",
+ SUAUTHFILE));
+ return DENY;
+ }
+
+ while (fgets(temp, sizeof(temp), authfile_fd) != NULL) {
+ lines++;
+
+ if (temp[endline = strlen(temp) - 1] != '\n') {
+ SYSLOG((LOG_ERR,
+ "%s, line %d: line too long or missing newline",
+ SUAUTHFILE, lines));
+ continue;
+ }
+
+ while (endline > 0 && (temp[endline-1] == ' '
+ || temp[endline-1] == '\t' || temp[endline-1] == '\n'))
+ endline--;
+ temp[endline] = '\0';
+
+ posn = 0;
+ while (temp[posn] == ' ' || temp[posn] == '\t')
+ posn++;
+
+ if (temp[posn] == '\n' || temp[posn] == '#' || temp[posn] == '\0') {
+ continue;
+ }
+ if (!(to_users = strtok(temp + posn, field))
+ || !(from_users = strtok((char *)NULL, field))
+ || !(action = strtok((char *)NULL, field))
+ || strtok((char *)NULL, field)) {
+ SYSLOG((LOG_ERR, "%s, line %d. Bad number of fields.\n",
+ SUAUTHFILE, lines));
+ continue;
+ }
+
+ if (!applies(wanted_id, to_users))
+ continue;
+ if (!applies(actual_id, from_users))
+ continue;
+ if (!strcmp(action, "DENY")) {
+ SYSLOG((pwent.pw_uid ? LOG_NOTICE : LOG_WARN,
+ "DENIED su from `%s' to `%s' (%s)\n",
+ actual_id, wanted_id, SUAUTHFILE));
+ fprintf(stderr, _("Access to su to that account DENIED.\n"));
+ fclose(authfile_fd);
+ return DENY;
+ } else if (!strcmp(action, "NOPASS")) {
+ SYSLOG((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
+ "NO password asked for su from `%s' to `%s' (%s)\n",
+ actual_id, wanted_id, SUAUTHFILE));
+ fprintf(stderr, _("Password authentication bypassed.\n"));
+ fclose(authfile_fd);
+ return NOPWORD;
+ } else if (!strcmp(action, "OWNPASS")) {
+ SYSLOG((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
+ "su from `%s' to `%s': asking for user's own password (%s)\n",
+ actual_id, wanted_id, SUAUTHFILE));
+ fprintf(stderr, _("Please enter your OWN password as authentication.\n"));
+ fclose(authfile_fd);
+ return OWNPWORD;
+ } else {
+ SYSLOG((LOG_ERR, "%s, line %d: unrecognised action!\n",
+ SUAUTHFILE, lines));
+ }
+ }
+ fclose(authfile_fd);
+ return NOACTION;
+}
+
+static int
+applies(const char *single, char *list)
+{
+ const char split[] = ", ";
+ char *tok;
+
+ int state = 0;
+
+ for (tok = strtok(list, split); tok != NULL; tok = strtok(NULL, split)) {
+
+ if (!strcmp(tok, "ALL")) {
+ if (state != 0) {
+ SYSLOG((LOG_ERR,
+ "%s, line %d: ALL in bad place\n",
+ SUAUTHFILE, lines));
+ return 0;
+ }
+ state = 1;
+ } else if (!strcmp(tok, "EXCEPT")) {
+ if (state != 1) {
+ SYSLOG((LOG_ERR,
+ "%s, line %d: EXCEPT in bas place\n",
+ SUAUTHFILE, lines));
+ return 0;
+ }
+ state = 2;
+ } else if (!strcmp(tok, "GROUP")) {
+ if ((state != 0) && (state != 2)) {
+ SYSLOG((LOG_ERR,
+ "%s, line %d: GROUP in bad place\n",
+ SUAUTHFILE, lines));
+ return 0;
+ }
+ state = (state == 0) ? 3 : 4;
+ } else {
+ switch (state) {
+ case 0: /* No control words yet */
+ if (!strcmp(tok, single))
+ return 1;
+ break;
+ case 1: /* An all */
+ SYSLOG((LOG_ERR, "%s, line %d: expect another token after ALL\n",
+ SUAUTHFILE, lines));
+ return 0;
+ case 2: /* All except */
+ if (!strcmp(tok, single))
+ return 0;
+ break;
+ case 3: /* Group */
+ if (isgrp(single, tok))
+ return 1;
+ break;
+ case 4: /* All except group */
+ if (isgrp(single, tok))
+ return 0;
+ /* FALL THRU */
+ }
+ }
+ }
+ if ((state != 0) && (state != 3))
+ return 1;
+ return 0;
+}
+
+int
+isgrp(const char *name, const char *group)
+{
+ struct group *grp;
+
+ grp = getgrnam(group);
+
+ if (!grp || !grp->gr_mem)
+ return 0;
+
+ return is_on_list(grp->gr_mem, name);
+}
+#endif /* SU_ACCESS */
diff --git a/current/libmisc/sub.c b/current/libmisc/sub.c
new file mode 100644
index 00000000..88f2df03
--- /dev/null
+++ b/current/libmisc/sub.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1989 - 1991, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: sub.c,v 1.6 1999/03/07 19:14:43 marekm Exp $")
+
+#include <sys/types.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <pwd.h>
+
+#define BAD_SUBROOT2 "invalid root `%s' for user `%s'\n"
+#define NO_SUBROOT2 "no subsystem root `%s' for user `%s'\n"
+
+/*
+ * subsystem - change to subsystem root
+ *
+ * A subsystem login is indicated by the presense of a "*" as
+ * the first character of the login shell. The given home
+ * directory will be used as the root of a new filesystem which
+ * the user is actually logged into.
+ */
+
+void
+subsystem(const struct passwd *pw)
+{
+ /*
+ * The new root directory must begin with a "/" character.
+ */
+
+ if (pw->pw_dir[0] != '/') {
+ printf(_("Invalid root directory \"%s\"\n"), pw->pw_dir);
+ SYSLOG((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name));
+ closelog();
+ exit (1);
+ }
+
+ /*
+ * The directory must be accessible and the current process
+ * must be able to change into it.
+ */
+
+ if (chdir (pw->pw_dir) || chroot (pw->pw_dir)) {
+ printf(_("Can't change root directory to \"%s\"\n"), pw->pw_dir);
+ SYSLOG((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));
+ closelog();
+ exit (1);
+ }
+}
diff --git a/current/libmisc/sulog.c b/current/libmisc/sulog.c
new file mode 100644
index 00000000..3de68692
--- /dev/null
+++ b/current/libmisc/sulog.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1989 - 1992, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: sulog.c,v 1.5 2000/08/26 18:27:17 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <time.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "getdef.h"
+
+/*
+ * sulog - log a SU command execution result
+ */
+
+void
+sulog(const char *tty, int success, const char *oldname, const char *name)
+{
+ char *sulog_file;
+ time_t now;
+ struct tm *tm;
+ FILE *fp;
+ mode_t oldmask;
+
+ if ((sulog_file = getdef_str("SULOG_FILE")) == (char *) 0)
+ return;
+
+ oldmask = umask(077);
+ fp = fopen(sulog_file, "a+");
+ umask(oldmask);
+ if (fp == (FILE *) 0)
+ return; /* can't open or create logfile */
+
+ time(&now);
+ tm = localtime(&now);
+
+ fprintf(fp, "SU %.02d/%.02d %.02d:%.02d %c %.6s %s-%s\n",
+ tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
+ success ? '+':'-', tty, oldname, name);
+
+ fflush(fp);
+ fclose(fp);
+}
diff --git a/current/libmisc/ttytype.c b/current/libmisc/ttytype.c
new file mode 100644
index 00000000..965dc7f1
--- /dev/null
+++ b/current/libmisc/ttytype.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: ttytype.c,v 1.5 1997/12/07 23:27:10 marekm Exp $")
+
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "getdef.h"
+
+extern char *getenv();
+
+/*
+ * ttytype - set ttytype from port to terminal type mapping database
+ */
+
+void
+ttytype(const char *line)
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+ char *typefile;
+ char *cp;
+ char type[BUFSIZ];
+ char port[BUFSIZ];
+
+ if (getenv ("TERM"))
+ return;
+ if ((typefile=getdef_str("TTYTYPE_FILE")) == NULL )
+ return;
+ if (access(typefile, F_OK))
+ return;
+
+ if (! (fp = fopen (typefile, "r"))) {
+ perror (typefile);
+ return;
+ }
+ while (fgets(buf, sizeof buf, fp)) {
+ if (buf[0] == '#')
+ continue;
+
+ if ((cp = strchr (buf, '\n')))
+ *cp = '\0';
+
+#if defined(SUN) || defined(BSD) || defined(SUN4)
+ if ((sscanf (buf, "%s \"%*[^\"]\" %s", port, type) == 2 ||
+ sscanf (buf, "%s %*s %s", port, type) == 2) &&
+ strcmp (line, port) == 0)
+ break;
+#else /* USG */
+ if (sscanf (buf, "%s %s", type, port) == 2 &&
+ strcmp (line, port) == 0)
+ break;
+#endif
+ }
+ if (! feof (fp) && ! ferror (fp))
+ addenv("TERM", type);
+
+ fclose (fp);
+}
diff --git a/current/libmisc/tz.c b/current/libmisc/tz.c
new file mode 100644
index 00000000..9449f6d8
--- /dev/null
+++ b/current/libmisc/tz.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: tz.c,v 1.4 1998/01/29 23:22:36 marekm Exp $")
+
+#include <stdio.h>
+#include <string.h>
+#include "defines.h"
+#include "getdef.h"
+
+/*
+ * tz - return local timezone name
+ *
+ * tz() determines the name of the local timezone by reading the
+ * contents of the file named by ``fname''.
+ */
+
+char *
+tz(const char *fname)
+{
+ FILE *fp = 0;
+ static char tzbuf[BUFSIZ];
+ const char *def_tz;
+
+ if ((fp = fopen(fname,"r")) == NULL ||
+ fgets (tzbuf, sizeof (tzbuf), fp) == NULL) {
+ if (! (def_tz = getdef_str ("ENV_TZ")) || def_tz[0] == '/')
+ def_tz = "TZ=CST6CDT";
+
+ strcpy (tzbuf, def_tz);
+ } else
+ tzbuf[strlen(tzbuf) - 1] = '\0';
+
+ if (fp)
+ (void) fclose(fp);
+
+ return tzbuf;
+}
diff --git a/current/libmisc/ulimit.c b/current/libmisc/ulimit.c
new file mode 100644
index 00000000..e99dab22
--- /dev/null
+++ b/current/libmisc/ulimit.c
@@ -0,0 +1,34 @@
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: ulimit.c,v 1.2 1997/12/07 23:27:11 marekm Exp $")
+
+#if HAVE_ULIMIT_H
+#include <ulimit.h>
+
+#ifndef UL_SETFSIZE
+#ifdef UL_SFILLIM
+#define UL_SETFSIZE UL_SFILLIM
+#else
+#define UL_SETFSIZE 2
+#endif
+#endif
+
+#elif HAVE_SYS_RESOURCE_H
+#include <sys/time.h> /* for struct timeval on sunos4 */
+/* XXX - is the above ok or should it be <time.h> on ultrix? */
+#include <sys/resource.h>
+#endif
+
+void
+set_filesize_limit(int blocks)
+{
+#if HAVE_ULIMIT_H
+ ulimit(UL_SETFSIZE, blocks);
+#elif defined(RLIMIT_FSIZE)
+ struct rlimit rlimit_fsize;
+
+ rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
+ setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
+#endif
+}
diff --git a/current/libmisc/utmp.c b/current/libmisc/utmp.c
new file mode 100644
index 00000000..bc020a2a
--- /dev/null
+++ b/current/libmisc/utmp.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "defines.h"
+
+#include <utmp.h>
+
+#if HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "rcsid.h"
+RCSID("$Id: utmp.c,v 1.8 1999/06/07 16:40:44 marekm Exp $")
+
+#if HAVE_UTMPX_H
+extern struct utmpx utxent;
+#endif
+extern struct utmp utent;
+
+extern struct utmp *getutent();
+extern struct utmp *getutline();
+extern void setutent();
+extern void endutent();
+extern time_t time();
+extern char *ttyname();
+extern long lseek();
+
+#define NO_UTENT \
+ "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
+#define NO_TTY \
+ "Unable to determine your tty name."
+
+/*
+ * checkutmp - see if utmp file is correct for this process
+ *
+ * System V is very picky about the contents of the utmp file
+ * and requires that a slot for the current process exist.
+ * The utmp file is scanned for an entry with the same process
+ * ID. If no entry exists the process exits with a message.
+ *
+ * The "picky" flag is for network and other logins that may
+ * use special flags. It allows the pid checks to be overridden.
+ * This means that getty should never invoke login with any
+ * command line flags.
+ */
+
+#if defined(__linux__) /* XXX */
+
+void
+checkutmp(int picky)
+{
+ char *line;
+ struct utmp *ut;
+ pid_t pid = getpid();
+
+ setutent();
+
+ /* First, try to find a valid utmp entry for this process. */
+ while ((ut = getutent()))
+ if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
+ (ut->ut_type==LOGIN_PROCESS || ut->ut_type==USER_PROCESS))
+ break;
+
+ /* If there is one, just use it, otherwise create a new one. */
+ if (ut) {
+ utent = *ut;
+ } else {
+ if (picky) {
+ puts(NO_UTENT);
+ exit(1);
+ }
+ line = ttyname(0);
+ if (!line) {
+ puts(NO_TTY);
+ exit(1);
+ }
+ if (strncmp(line, "/dev/", 5) == 0)
+ line += 5;
+ memset((void *) &utent, 0, sizeof utent);
+ utent.ut_type = LOGIN_PROCESS;
+ utent.ut_pid = pid;
+ strncpy(utent.ut_line, line, sizeof utent.ut_line);
+ /* XXX - assumes /dev/tty?? */
+ strncpy(utent.ut_id, utent.ut_line + 3, sizeof utent.ut_id);
+ strcpy(utent.ut_user, "LOGIN");
+ time(&utent.ut_time);
+ }
+}
+
+#elif defined(LOGIN_PROCESS)
+
+void
+checkutmp(int picky)
+{
+ char *line;
+ struct utmp *ut;
+#if HAVE_UTMPX_H
+ struct utmpx *utx;
+#endif
+ pid_t pid = getpid();
+
+#if HAVE_UTMPX_H
+ setutxent();
+#endif
+ setutent();
+
+ if (picky) {
+#if HAVE_UTMPX_H
+ while ((utx = getutxent()))
+ if (utx->ut_pid == pid)
+ break;
+
+ if (utx)
+ utxent = *utx;
+#endif
+ while ((ut = getutent()))
+ if (ut->ut_pid == pid)
+ break;
+
+ if (ut)
+ utent = *ut;
+
+#if HAVE_UTMPX_H
+ endutxent();
+#endif
+ endutent();
+
+ if (!ut) {
+ puts(NO_UTENT);
+ exit(1);
+ }
+#ifndef UNIXPC
+
+ /*
+ * If there is no ut_line value in this record, fill
+ * it in by getting the TTY name and stuffing it in
+ * the structure. The UNIX/PC is broken in this regard
+ * and needs help ...
+ */
+
+ if (utent.ut_line[0] == '\0')
+#endif /* !UNIXPC */
+ {
+ if (!(line = ttyname(0))) {
+ puts(NO_TTY);
+ exit(1);
+ }
+ if (strncmp(line, "/dev/", 5) == 0)
+ line += 5;
+ strncpy(utent.ut_line, line, sizeof utent.ut_line);
+#if HAVE_UTMPX_H
+ strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
+#endif
+ }
+ } else {
+ if (!(line = ttyname(0))) {
+ puts(NO_TTY);
+ exit(1);
+ }
+ if (strncmp(line, "/dev/", 5) == 0)
+ line += 5;
+
+ strncpy (utent.ut_line, line, sizeof utent.ut_line);
+ if ((ut = getutline(&utent)))
+ strncpy(utent.ut_id, ut->ut_id, sizeof ut->ut_id);
+
+ strcpy(utent.ut_user, "LOGIN");
+ utent.ut_pid = getpid();
+ utent.ut_type = LOGIN_PROCESS;
+ time(&utent.ut_time);
+#if HAVE_UTMPX_H
+ strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
+ if ((utx = getutxline(&utxent)))
+ strncpy(utxent.ut_id, utx->ut_id, sizeof utxent.ut_id);
+
+ strcpy(utxent.ut_user, "LOGIN");
+ utxent.ut_pid = utent.ut_pid;
+ utxent.ut_type = utent.ut_type;
+ gettimeofday((struct timeval *) &utxent.ut_tv, NULL);
+ utent.ut_time = utxent.ut_tv.tv_sec;
+#endif
+ }
+}
+
+#else /* !USG */
+
+void
+checkutmp(int picky)
+{
+ char *line;
+
+ /*
+ * Hand-craft a new utmp entry.
+ */
+
+ memzero(&utent, sizeof utent);
+ if (! (line = ttyname (0))) {
+ puts (NO_TTY);
+ exit (1);
+ }
+ if (strncmp (line, "/dev/", 5) == 0)
+ line += 5;
+
+ (void) strncpy (utent.ut_line, line, sizeof utent.ut_line);
+ (void) time (&utent.ut_time);
+}
+
+#endif /* !USG */
+
+
+/*
+ * Some systems already have updwtmp() and possibly updwtmpx(). Others
+ * don't, so we re-implement these functions if necessary. --marekm
+ */
+
+#ifndef HAVE_UPDWTMP
+static void
+updwtmp(const char *filename, const struct utmp *ut)
+{
+ int fd;
+
+ fd = open(filename, O_APPEND | O_WRONLY, 0);
+ if (fd >= 0) {
+ write(fd, (const char *) ut, sizeof(*ut));
+ close(fd);
+ }
+}
+#endif /* ! HAVE_UPDWTMP */
+
+#ifdef HAVE_UTMPX_H
+#ifndef HAVE_UPDWTMPX
+static void
+updwtmpx(const char *filename, const struct utmpx *utx)
+{
+ int fd;
+
+ fd = open(filename, O_APPEND | O_WRONLY, 0);
+ if (fd >= 0) {
+ write(fd, (const char *) utx, sizeof(*utx));
+ close(fd);
+ }
+}
+#endif /* ! HAVE_UPDWTMPX */
+#endif /* ! HAVE_UTMPX_H */
+
+
+/*
+ * setutmp - put a USER_PROCESS entry in the utmp file
+ *
+ * setutmp changes the type of the current utmp entry to
+ * USER_PROCESS. the wtmp file will be updated as well.
+ */
+
+#if defined(__linux__) /* XXX */
+
+void
+setutmp(const char *name, const char *line, const char *host)
+{
+ utent.ut_type = USER_PROCESS;
+ strncpy(utent.ut_user, name, sizeof utent.ut_user);
+ time(&utent.ut_time);
+ /* other fields already filled in by checkutmp above */
+ setutent();
+ pututline(&utent);
+ endutent();
+ updwtmp(_WTMP_FILE, &utent);
+}
+
+#elif HAVE_UTMPX_H
+
+void
+setutmp(const char *name, const char *line, const char *host)
+{
+ struct utmp *utmp, utline;
+ struct utmpx *utmpx, utxline;
+ pid_t pid = getpid ();
+ int found_utmpx = 0, found_utmp = 0;
+
+ /*
+ * The canonical device name doesn't include "/dev/"; skip it
+ * if it is already there.
+ */
+
+ if (strncmp (line, "/dev/", 5) == 0)
+ line += 5;
+
+ /*
+ * Update utmpx. We create an empty entry in case there is
+ * no matching entry in the utmpx file.
+ */
+
+ setutxent ();
+ setutent ();
+
+ while (utmpx = getutxent ()) {
+ if (utmpx->ut_pid == pid) {
+ found_utmpx = 1;
+ break;
+ }
+ }
+ while (utmp = getutent ()) {
+ if (utmp->ut_pid == pid) {
+ found_utmp = 1;
+ break;
+ }
+ }
+
+ /*
+ * If the entry matching `pid' cannot be found, create a new
+ * entry with the device name in it.
+ */
+
+ if (! found_utmpx) {
+ memset ((void *) &utxline, 0, sizeof utxline);
+ strncpy (utxline.ut_line, line, sizeof utxline.ut_line);
+ utxline.ut_pid = getpid ();
+ } else {
+ utxline = *utmpx;
+ if (strncmp (utxline.ut_line, "/dev/", 5) == 0) {
+ memmove (utxline.ut_line, utxline.ut_line + 5,
+ sizeof utxline.ut_line - 5);
+ utxline.ut_line[sizeof utxline.ut_line - 5] = '\0';
+ }
+ }
+ if (! found_utmp) {
+ memset ((void *) &utline, 0, sizeof utline);
+ strncpy (utline.ut_line, utxline.ut_line,
+ sizeof utline.ut_line);
+ utline.ut_pid = utxline.ut_pid;
+ } else {
+ utline = *utmp;
+ if (strncmp (utline.ut_line, "/dev/", 5) == 0) {
+ memmove (utline.ut_line, utline.ut_line + 5,
+ sizeof utline.ut_line - 5);
+ utline.ut_line[sizeof utline.ut_line - 5] = '\0';
+ }
+ }
+
+ /*
+ * Fill in the fields in the utmpx entry and write it out. Do
+ * the utmp entry at the same time to make sure things don't
+ * get messed up.
+ */
+
+ strncpy (utxline.ut_user, name, sizeof utxline.ut_user);
+ strncpy (utline.ut_user, name, sizeof utline.ut_user);
+
+ utline.ut_type = utxline.ut_type = USER_PROCESS;
+
+ gettimeofday(&utxline.ut_tv, NULL);
+ utline.ut_time = utxline.ut_tv.tv_sec;
+
+ strncpy(utxline.ut_host, host ? host : "", sizeof utxline.ut_host);
+
+ pututxline (&utxline);
+ pututline (&utline);
+
+ updwtmpx(_WTMP_FILE "x", &utxline);
+ updwtmp(_WTMP_FILE, &utline);
+
+ utxent = utxline;
+ utent = utline;
+}
+
+#else /* !SVR4 */
+
+void
+setutmp(const char *name, const char *line)
+{
+ struct utmp utmp;
+ int fd;
+ int found = 0;
+
+ if ((fd = open(_UTMP_FILE, O_RDWR)) < 0)
+ return;
+
+#if !defined(SUN) && !defined(BSD) && !defined(SUN4) /* XXX */
+ while (!found && read(fd, (char *)&utmp, sizeof utmp) == sizeof utmp) {
+ if (! strncmp (line, utmp.ut_line, (int) sizeof utmp.ut_line))
+ found++;
+ }
+#endif
+
+ if (! found) {
+
+ /*
+ * This is a brand-new entry. Clear it out and fill it in
+ * later.
+ */
+
+ memzero(&utmp, sizeof utmp);
+ strncpy(utmp.ut_line, line, (int) sizeof utmp.ut_line);
+ }
+
+ /*
+ * Fill in the parts of the UTMP entry. BSD has just the name,
+ * while System V has the name, PID and a type.
+ */
+
+ strncpy(utmp.ut_user, name, sizeof utent.ut_user);
+#ifdef USER_PROCESS
+ utmp.ut_type = USER_PROCESS;
+ utmp.ut_pid = getpid ();
+#endif
+
+ /*
+ * Put in the current time (common to everyone)
+ */
+
+ (void) time (&utmp.ut_time);
+
+#ifdef UT_HOST
+ /*
+ * Update the host name field for systems with networking support
+ */
+
+ (void) strncpy (utmp.ut_host, utent.ut_host, (int) sizeof utmp.ut_host);
+#endif
+
+ /*
+ * Locate the correct position in the UTMP file for this
+ * entry.
+ */
+
+#ifdef HAVE_TTYSLOT
+ (void) lseek (fd, (off_t) (sizeof utmp) * ttyslot (), SEEK_SET);
+#else
+ if (found) /* Back up a splot */
+ lseek (fd, (off_t) - sizeof utmp, SEEK_CUR);
+ else /* Otherwise, go to the end of the file */
+ lseek (fd, (off_t) 0, SEEK_END);
+#endif
+
+ /*
+ * Scribble out the new entry and close the file. We're done
+ * with UTMP, next we do WTMP (which is real easy, put it on
+ * the end of the file.
+ */
+
+ (void) write (fd, (char *) &utmp, sizeof utmp);
+ (void) close (fd);
+
+ updwtmp(_WTMP_FILE, &utmp);
+ utent = utmp;
+}
+
+#endif /* SVR4 */
diff --git a/current/libmisc/valid.c b/current/libmisc/valid.c
new file mode 100644
index 00000000..8559638e
--- /dev/null
+++ b/current/libmisc/valid.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 1989 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: valid.c,v 1.4 1999/03/07 19:14:44 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+
+/*
+ * valid - compare encrypted passwords
+ *
+ * Valid() compares the DES encrypted password from the password file
+ * against the password which the user has entered after it has been
+ * encrypted using the same salt as the original. Entries which do
+ * not have a password file entry have a NULL pw_name field and this
+ * is used to indicate that a dummy salt must be used to encrypt the
+ * password anyway.
+ */
+
+int
+valid(const char *password, const struct passwd *ent)
+{
+ const char *encrypted;
+ const char *salt;
+
+ /*
+ * Start with blank or empty password entries. Always encrypt
+ * a password if no such user exists. Only if the ID exists and
+ * the password is really empty do you return quickly. This
+ * routine is meant to waste CPU time.
+ */
+
+ if (ent->pw_name && ! ent->pw_passwd[0]) {
+ if (! password[0])
+ return (1); /* user entered nothing */
+ else
+ return (0); /* user entered something! */
+ }
+
+ /*
+ * If there is no entry then we need a salt to use.
+ */
+
+ if (ent->pw_name == (char *) 0 || ent->pw_passwd[0] == '\0') {
+ salt = "xx";
+ } else {
+ salt = ent->pw_passwd;
+ }
+
+ /*
+ * Now, perform the encryption using the salt from before on
+ * the users input. Since we always encrypt the string, it
+ * should be very difficult to determine if the user exists by
+ * looking at execution time.
+ */
+
+ encrypted = pw_encrypt(password, salt);
+
+ /*
+ * One last time we must deal with there being no password file
+ * entry for the user. We use the pw_name == NULL idiom to
+ * cause non-existent users to not be validated.
+ */
+
+ if (ent->pw_name && strcmp(encrypted, ent->pw_passwd) == 0)
+ return (1);
+ else
+ return (0);
+}
diff --git a/current/libmisc/xmalloc.c b/current/libmisc/xmalloc.c
new file mode 100644
index 00000000..e85ae26c
--- /dev/null
+++ b/current/libmisc/xmalloc.c
@@ -0,0 +1,38 @@
+/* Replacements for malloc and strdup with error checking. Too trivial
+ to be worth copyrighting :-). I did that because a lot of code used
+ malloc and strdup without checking for NULL pointer, and I like some
+ message better than a core dump... --marekm
+
+ Yeh, but. Remember that bailing out might leave the system in some
+ bizarre state. You really want to put in error checking, then add
+ some back-out failure recovery code. -- jfh */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID("$Id: xmalloc.c,v 1.3 1998/12/28 20:34:56 marekm Exp $")
+
+#include <stdio.h>
+
+#include "defines.h"
+
+extern char *malloc();
+
+char *
+xmalloc(size_t size)
+{
+ char *ptr;
+
+ ptr = malloc(size);
+ if (!ptr && size) {
+ fprintf(stderr, _("malloc(%d) failed\n"), (int) size);
+ exit(13);
+ }
+ return ptr;
+}
+
+char *
+xstrdup(const char *str)
+{
+ return strcpy(xmalloc(strlen(str) + 1), str);
+}
diff --git a/current/ltconfig b/current/ltconfig
new file mode 100755
index 00000000..65ec6f65
--- /dev/null
+++ b/current/ltconfig
@@ -0,0 +1,3017 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != "Xset"; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) PATH_SEPARATOR=';' ;;
+ *) PATH_SEPARATOR=':' ;;
+ esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != "Xset"; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+ test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running ltconfig again with it.
+ ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf "%s\n"'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.3
+TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+ case "$option" in
+ -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval "$prev=\$option"
+ prev=
+ continue
+ fi
+
+ case "$option" in
+ --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+ --debug enable verbose shell tracing
+ --disable-shared do not build shared libraries
+ --disable-static do not build static libraries
+ --disable-fast-install do not optimize for fast installation
+ --enable-dlopen enable dlopen support
+ --enable-win32-dll enable building dlls on win32 hosts
+ --help display this help and exit
+ --no-verify do not verify that HOST is a valid host type
+-o, --output=FILE specify the output file [default=$default_ofile]
+ --quiet same as \`--silent'
+ --silent do not print informational messages
+ --srcdir=DIR find \`config.guess' in DIR
+ --version output version information and exit
+ --with-gcc assume that the GNU C compiler will be used
+ --with-gnu-ld assume that the C compiler uses the GNU linker
+ --disable-lock disable file locking
+ --cache-file=FILE configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --disable-shared) enable_shared=no ;;
+
+ --disable-static) enable_static=no ;;
+
+ --disable-fast-install) enable_fast_install=no ;;
+
+ --enable-dlopen) enable_dlopen=yes ;;
+
+ --enable-win32-dll) enable_win32_dll=yes ;;
+
+ --quiet | --silent) silent=yes ;;
+
+ --srcdir) prev=srcdir ;;
+ --srcdir=*) srcdir="$optarg" ;;
+
+ --no-verify) verify_host=no ;;
+
+ --output | -o) prev=ofile ;;
+ --output=*) ofile="$optarg" ;;
+
+ --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+ --with-gcc) with_gcc=yes ;;
+ --with-gnu-ld) with_gnu_ld=yes ;;
+
+ --disable-lock) need_locks=no ;;
+
+ --cache-file=*) cache_file="$optarg" ;;
+
+ -*)
+ echo "$progname: unrecognized option \`$option'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ if test -z "$ltmain"; then
+ ltmain="$option"
+ elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+# echo "$progname: warning \`$option' is not a valid host type" 1>&2
+# fi
+ host="$option"
+ else
+ echo "$progname: too many arguments" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if test -z "$ltmain"; then
+ echo "$progname: you must specify a LTMAIN file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+if test ! -f "$ltmain"; then
+ echo "$progname: \`$ltmain' does not exist" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+ case "$arg" in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ltconfig_args="$ltconfig_args '$arg'" ;;
+ *) ltconfig_args="$ltconfig_args $arg" ;;
+ esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+ echo "loading cache $cache_file within ltconfig"
+ . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+ # Assume the source directory is the same one as the path to LTMAIN.
+ srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+ test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+ # Check for config.guess and config.sub.
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/config.guess; then
+ ac_aux_dir=$ac_dir
+ break
+ fi
+ done
+ if test -z "$ac_aux_dir"; then
+ echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+ ac_config_guess=$ac_aux_dir/config.guess
+ ac_config_sub=$ac_aux_dir/config.sub
+
+ # Make sure we can run config.sub.
+ if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+ else
+ echo "$progname: cannot run $ac_config_sub" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+ host_alias=$host
+ case "$host_alias" in
+ "")
+ if host_alias=`$SHELL $ac_config_guess`; then :
+ else
+ echo "$progname: cannot guess host type; you must specify one" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+ host=`$SHELL $ac_config_sub $host_alias`
+ echo "$ac_t$host" 1>&6
+
+ # Make sure the host verified.
+ test -z "$host" && exit 1
+
+elif test -z "$host"; then
+ echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+else
+ host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+ result=no
+
+ echo $ac_n "checking for ranlib... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+ RANLIB="ranlib"
+ result="ranlib"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+ # If CC is not set, then try to find GCC or a usable CC.
+ if test -z "$CC"; then
+ echo $ac_n "checking for gcc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+ fi
+
+ # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+ if test -z "$CC"; then
+ echo $ac_n "checking for cc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ cc_rejected=no
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+ if test "$dir/cc" = "/usr/ucb/cc"; then
+ cc_rejected=yes
+ continue
+ fi
+ CC="cc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test $cc_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same name, so the bogon will be chosen
+ # first if we set CC to just the name; use the full file name.
+ shift
+ set dummy "$dir/cc" "$@"
+ shift
+ CC="$@"
+ fi
+ fi
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$CC"; then
+ echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+ exit 1
+ fi
+ fi
+
+ # Now see if the compiler is really GCC.
+ with_gcc=no
+ echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+ echo "$progname:581: checking whether we are using GNU C" >&5
+
+ $rm conftest.c
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+ if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ with_gcc=yes
+ fi
+ $rm conftest.c
+ echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_exeext="no"
+ $rm conftest*
+ echo 'main () { return 0; }' > conftest.c
+ echo "$progname:629: checking for executable suffix" >& 5
+ if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c | *.err | *.$objext ) ;;
+ *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+ else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+ exeext=""
+else
+ exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+ wl='-Wl,'
+ link_static_flag='-static'
+
+ case "$host_os" in
+ beos* | irix5* | irix6* | osf3* | osf4*)
+ # PIC is the default for these OSes.
+ ;;
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # we not sure about C++ programs.
+ link_static_flag="$link_static_flag ${wl}-lC"
+ ;;
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ pic_flag='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ pic_flag=-Kconform_pic
+ fi
+ ;;
+ *)
+ pic_flag='-fPIC'
+ ;;
+ esac
+else
+ # PORTME Check for PIC flags for the system compiler.
+ case "$host_os" in
+ aix3* | aix4*)
+ # All AIX code is PIC.
+ link_static_flag='-bnso -bI:/lib/syscalls.exp'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better link_static_flag that works with the bundled CC?
+ wl='-Wl,'
+ link_static_flag="${wl}-a ${wl}archive"
+ pic_flag='+Z'
+ ;;
+
+ irix5* | irix6*)
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+
+ osf3* | osf4*)
+ # All OSF/1 code is PIC.
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ pic_flag='-Kpic'
+ link_static_flag='-dn'
+ special_shlib_compile_flags='-belf'
+ ;;
+
+ solaris*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ sunos4*)
+ pic_flag='-PIC'
+ link_static_flag='-Bstatic'
+ wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ uts4*)
+ pic_flag='-pic'
+ link_static_flag='-Bstatic'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ pic_flag='-Kconform_pic'
+ link_static_flag='-Bstatic'
+ fi
+ ;;
+ *)
+ can_build_shared=no
+ ;;
+ esac
+fi
+
+if test -n "$pic_flag"; then
+ echo "$ac_t$pic_flag" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $pic_flag -DPIC"
+ echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+ if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ case "$host_os" in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+ # create non-PIC objects. So, if there were any warnings, we assume that
+ # PIC is not supported.
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ can_build_shared=no
+ pic_flag=
+ else
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ fi
+ ;;
+ *)
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ ;;
+ esac
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ can_build_shared=no
+ pic_flag=
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_c_o=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ compiler_c_o=no
+ echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_o_lo=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_o_lo=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_o_lo=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t$hard_links" 1>&6
+ $rm conftest*
+ if test "$hard_links" = no; then
+ echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+ echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_rtti_exceptions=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_rtti_exceptions=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_rtti_exceptions=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+ echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then :
+ else
+ echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ echo "$ac_t$link_static_flag" 1>&6
+else
+ echo "$ac_t"none 1>&6
+ link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+ # Check to see if we can use ln -s, or we need hard links.
+ echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+ $rm conftest.dat
+ if ln -s X conftest.dat 2>/dev/null; then
+ $rm conftest.dat
+ LN_S="ln -s"
+ else
+ LN_S=ln
+ fi
+ if test "$LN_S" = "ln -s"; then
+ echo "$ac_t"yes 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+ ac_prog=ld
+ if test "$with_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+ echo "$progname:991: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we are not using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+ echo "$progname:1015: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+ echo "$progname:1018: checking for non-GNU ld" >&5
+ fi
+
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ fi
+
+ if test -n "$LD"; then
+ echo "$ac_t$LD" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$LD"; then
+ echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+ exit 1
+ fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$with_gcc" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case "$host_os" in
+ aix3* | aix4*)
+ # On AIX, the GNU linker is very broken
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+ $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols'
+
+ archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+ _lt_hint=1;
+ for symbol in `cat $export_symbols`; do
+ echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done~
+ test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+ $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+ old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a'
+ ;;
+
+ netbsd*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+ # can we support soname and/or expsyms with a.out? -oliva
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case "$host_os" in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4*)
+ hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+ hardcode_libdir_separator=':'
+ if test "$with_gcc" = yes; then
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ shared_flag='-shared'
+ else
+ shared_flag='${wl}-bM:SRE'
+ hardcode_direct=yes
+ fi
+ allow_undefined_flag=' ${wl}-berok'
+ archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+ archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+ case "$host_os" in aix4.[01]|aix4.[01].*)
+ # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+ always_export_symbols=yes ;;
+ esac
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+ fix_srcfile_path='`cygpath -w $srcfile`'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case "$host_os" in
+ hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF
+ fi
+ hardcode_libdir_flag_spec='${wl}-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+ ;;
+
+ osf3* | osf4*)
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case "$host_os" in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs'
+ archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+ echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+ case "$NM" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -p"
+ break
+ else
+ NM=${NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$NM" && NM=nm
+ ;;
+ esac
+ echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ symcode='[BDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+ global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ $rm conftest*
+ cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ echo "$progname:1592: checking if global_symbol_pipe works" >&5
+ if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$objext conftstm.$objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$save_LIBS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ global_symbol_pipe=
+ fi
+done
+if test "$pipe_works" = yes; then
+ echo "${ac_t}ok" 1>&6
+else
+ echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4*)
+ version_type=linux
+ # AIX has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ # We preserve .a as extension for shared libraries though AIX4.2
+ # and later linker supports .so
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+ shlibpath_var=LIBPATH
+ deplibs_check_method=pass_all
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ deplibs_check_method=pass_all
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+bsdi4*)
+ version_type=linux
+ library_names_spec='${libname}.so$major ${libname}.so'
+ soname_spec='${libname}.so'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ if test "$with_gcc" = yes; then
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+ else
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ fi
+ dynamic_linker='Win32 ld.exe'
+ deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ file_magic_cmd='${OBJDUMP} -f'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case "$version_type" in
+ freebsd-elf*)
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ deplibs_check_method=unknown
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_os" in
+ freebsd2* | freebsd3.[01]*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *) # from 3.2 on
+ shlibpath_overrides_runpath=no
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so.$major'
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+ case "$host_os" in
+ irix5*)
+ libsuff= shlibsuff=
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case "$LD" in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ deplibs_check_method='pass_all'
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+ if test -f /lib/ld.so.1; then
+ dynamic_linker='GNU ld.so'
+ else
+ # Only the GNU ld.so supports shared libraries on MkLinux.
+ case "$host_cpu" in
+ powerpc*) dynamic_linker=no ;;
+ *) dynamic_linker='Linux ld.so' ;;
+ esac
+ fi
+ ;;
+
+netbsd*)
+ version_type=sunos
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+openbsd*)
+ version_type=sunos
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ need_version=no
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4*)
+ version_type=osf
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method='file_magic COFF format alpha shared library'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ deplibs_check_method='pass_all'
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/lib/libc.so
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_vendor" in
+ ncr)
+ deplibs_check_method='pass_all'
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+ if test x$can_build_shared = xyes; then
+ test x$enable_win32_dll = xno && can_build_shared=no
+ echo "checking if package supports dlls... $can_build_shared" 1>&6
+ fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+ case "$deplibs_check_method" in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ test "$enable_shared" = yes && enable_static=no
+ ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+ lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2170: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2178 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2207: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2212 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2251: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2259 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2288: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2293 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2333: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2341 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+fi
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ fi
+
+ case "$lt_cv_dlopen" in
+ dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2395: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2400 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ if test "x$ac_cv_header_dlfcn_h" = xyes; then
+ CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ fi
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2433: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self=cross
+ else
+ cat > conftest.c <<EOF
+#line 2441 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); }
+
+EOF
+if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "$lt_cv_dlopen_self" = yes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self_static=cross
+ else
+ cat > conftest.c <<EOF
+#line 2514 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); }
+
+EOF
+if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self_static=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+ ;;
+ esac
+
+ case "$lt_cv_dlopen_self" in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case "$lt_cv_dlopen_self_static" in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+ # Now quote all the things that may contain metacharacters.
+ for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+ old_LD old_LDFLAGS old_LIBS \
+ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+ AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+ file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case "$var" in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case "$ltecho" in
+ *'\$0 --fallback-echo"')
+ ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+ ;;
+ esac
+
+ trap "$rm \"$ofile\"; exit 1" 1 2 15
+ echo "creating $ofile"
+ $rm "$ofile"
+ cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+ cfgfile="$ofile"
+ ;;
+
+*)
+ # Double-quote the variables that need it (for aesthetics).
+ for var in old_CC old_CFLAGS old_CPPFLAGS \
+ old_LD old_LDFLAGS old_LIBS \
+ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+ eval "$var=\\\"\$var\\\""
+ done
+
+ # Just create a config file.
+ cfgfile="$ofile.cfg"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ echo "creating $cfgfile"
+ $rm "$cfgfile"
+ cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+ ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+# $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+ echo '### END LIBTOOL CONFIG' >> "$ofile"
+ echo >> "$ofile"
+ case "$host_os" in
+ aix3*)
+ cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # Append the ltmain.sh script.
+ sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+
+ chmod +x "$ofile"
+ ;;
+
+*)
+ # Compile the libtool program.
+ echo "FIXME: would compile $ltmain"
+ ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/current/ltmain.sh b/current/ltmain.sh
new file mode 100644
index 00000000..ae10cad0
--- /dev/null
+++ b/current/ltmain.sh
@@ -0,0 +1,3975 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.3
+TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ case "$user_target" in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case "$user_target" in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $pic_flag -DPIC $srcfile"
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ # Now arrange that obj and lo_libobj become the same file
+ $show "$LN_S $obj $lo_libobj"
+ if $run $LN_S $obj $lo_libobj; then
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ command="$base_compile $srcfile"
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ C_compiler="$CC" # save it, to compile generated C sources
+ CC="$nonopt"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (!dll)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ compile_command="$CC"
+ finalize_command="$CC"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ linkopts=
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ lib_search_path=
+ fi
+ # now prepend the system-specific ones
+ eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ module=no
+ objs=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case "$arg" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: not more than one -exported-symbols argument allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case " $deplibs " in
+ *" $arg "*) ;;
+ *) deplibs="$deplibs $arg";;
+ esac
+ case " $lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir";;
+ esac
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ case ":$dllsearchpath:" in
+ ::) dllsearchpath="$dllsearchdir";;
+ *":$dllsearchdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+ esac
+ ;;
+ esac
+ ;;
+
+ -l*)
+ if test "$arg" = "-lc"; then
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # These systems don't actually have c library (as such)
+ continue
+ ;;
+ esac
+ elif test "$arg" = "-lm"; then
+ case "$host" in
+ *-*-cygwin* | *-*-beos*)
+ # These systems don't actually have math library (as such)
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.obj | *.a | *.lib)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # Read the .la file
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+ if test "X$installed" = Xyes; then
+ dir="$libdir"
+ else
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ fi
+
+ if test -n "$dependency_libs"; then
+ # Extract -R and -L from dependency_libs
+ temp_deplibs=
+ for deplib in $dependency_libs; do
+ case "$deplib" in
+ -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ case " $rpath $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ -L*) case "$compile_command $temp_deplibs " in
+ *" $deplib "*) ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ case " $lib_search_path " in
+ *" $temp_dir "*) ;;
+ *) lib_search_path="$lib_search_path $temp_dir";;
+ esac
+ ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ if test -z "$libdir"; then
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$deplibs$dependency_libs"
+ compile_command="$compile_command $dir/$old_library$dependency_libs"
+ finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+ continue
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking statically,
+ # we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # We need an absolute path.
+ case "$dir" in
+ [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+
+ # This is the magic to use -rpath.
+ # Skip directories that are in the system default run-time
+ # search path, unless they have been requested with -R.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+
+ lib_linked=yes
+ case "$hardcode_action" in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ deplibs="$deplibs $dir/$linklib"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ if test -n "$dllsearchpath"; then
+ dllsearchpath="$dllsearchpath:$dllsearchdir"
+ else
+ dllsearchpath="$dllsearchdir"
+ fi
+ ;;
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case "$host" in
+ *-*-sunos*)
+ compile_shlibpath="$compile_shlibpath$dir:"
+ ;;
+ esac
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ case ":$compile_shlibpath:" in
+ *":$dir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$dir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ relink)
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $absdir/$linklib"
+ deplibs="$deplibs $absdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$compile_command " in
+ *" -L$absdir "*) ;;
+ *) compile_command="$compile_command -L$absdir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$absdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$compile_shlibpath:" in
+ *":$absdir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$absdir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ *)
+ lib_linked=no
+ ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$finalize_command " in
+ *" -L$libdir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$finalize_shlibpath:" in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$dir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *.a | *.lib)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$outputname" in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+ dependency_libs="$deplibs"
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case "$version_type" in
+ none) ;;
+
+ irix)
+ major=`expr $current - $age + 1`
+ versuffix="$major.$revision"
+ verstring="sgi$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test $loop != 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="sgi$major.$iface:$verstring"
+ done
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ windows)
+ # Like Linux, but with '-' rather than '.', since we only
+ # want one extension on Windows 95.
+ major=`expr $current - $age`
+ versuffix="-$major-$age-$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ dependency_libs="$deplibs"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *)
+ # Add libc to deplibs on all other systems.
+ deplibs="$deplibs -lc"
+ ;;
+ esac
+ fi
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $output_objdir; then
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ else
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ if test "$build_libtool_libs" = yes; then
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case "$deplibs_check_method" in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $C_compiler -o conftest conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ $rm conftest
+ $C_compiler -o conftest conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case "$potliblink" in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) incase we are running --disable-static
+ for obj in $libobjs; do
+ oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"`
+ if test ! -f $oldobj; then
+ $show "${LN_S} $obj $oldobj"
+ $run ${LN_S} $obj $oldobj || exit $?
+ fi
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linkopts="$linkopts $flag"
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ *.lo | *.o | *.obj)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ $show "$LN_S $obj $libobj"
+ $run $LN_S $obj $libobj || exit $?
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ # Anything else should be a program.
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$compile_rpath " in
+ *" $libdir "*) ;;
+ *) compile_rpath="$compile_rpath $libdir" ;;
+ esac
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ # Create the binary in the object directory, then wrap it.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \
+ -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \
+ < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case "$host" in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case "$0" in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ link_against_libtool_libs='$link_against_libtool_libs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if (cd \"\$thisdir\" && eval \$relink_command); then :
+ else
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname$exeext'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ *-*-cygwin* | *-*-mingw | *-*-os2*)
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ # Ensure that we have .o objects in place incase we decided
+ # not to build a shared library, and have fallen back to building
+ # static libs even though --disable-static was passed!
+ for oldobj in $oldobjs; do
+ if test ! -f $oldobj; then
+ obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"`
+ $show "${LN_S} $obj $oldobj"
+ $run ${LN_S} $obj $oldobj || exit $?
+ fi
+ done
+
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ if test -n "$xrpath"; then
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ done
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ fi
+ $rm $output
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a | *.lib)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.o | *.obj)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir="$tmpdir/libtool-$$"
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/current/man/Makefile.am b/current/man/Makefile.am
new file mode 100644
index 00000000..16a40e7e
--- /dev/null
+++ b/current/man/Makefile.am
@@ -0,0 +1,21 @@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+SUBDIRS = pl
+
+man_MANS = chage.1 chfn.1 chsh.1 gpasswd.1 \
+ login.1 newgrp.1 passwd.1 su.1 \
+ shadow.3 \
+ dialups.5 faillog.5 limits.5 login.access.5 login.defs.5 \
+ passwd.5 porttime.5 shadow.5 suauth.5 \
+ chpasswd.8 dpasswd.8 faillog.8 \
+ groupadd.8 groupdel.8 groupmod.8 \
+ grpck.8 lastlog.8 logoutd.8 mkpasswd.8 newusers.8 \
+ pwck.8 pwconv.8 shadowconfig.8 \
+ useradd.8 userdel.8 usermod.8 vipw.8
+
+EXTRA_DIST = groups.1 id.1 pw_auth.3 pwauth.8 sulogin.8 ${man_MANS}
+
+# subdirectories for translated manual pages
+SUBDIRS = pl
+
diff --git a/current/man/Makefile.in b/current/man/Makefile.in
new file mode 100644
index 00000000..076af868
--- /dev/null
+++ b/current/man/Makefile.in
@@ -0,0 +1,471 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+# subdirectories for translated manual pages
+SUBDIRS = pl
+
+man_MANS = chage.1 chfn.1 chsh.1 gpasswd.1 login.1 newgrp.1 passwd.1 su.1 shadow.3 dialups.5 faillog.5 limits.5 login.access.5 login.defs.5 passwd.5 porttime.5 shadow.5 suauth.5 chpasswd.8 dpasswd.8 faillog.8 groupadd.8 groupdel.8 groupmod.8 grpck.8 lastlog.8 logoutd.8 mkpasswd.8 newusers.8 pwck.8 pwconv.8 shadowconfig.8 useradd.8 userdel.8 usermod.8 vipw.8
+
+
+EXTRA_DIST = groups.1 id.1 pw_auth.3 pwauth.8 sulogin.8 ${man_MANS}
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+man1dir = $(mandir)/man1
+man3dir = $(mandir)/man3
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+
+NROFF = nroff
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps man/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+install-man3:
+ $(mkinstalldirs) $(DESTDIR)$(man3dir)
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+uninstall-man3:
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+install-man5:
+ $(mkinstalldirs) $(DESTDIR)$(man5dir)
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \
+ done
+
+uninstall-man5:
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man5dir)/$$inst; \
+ done
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1 install-man3 install-man5 \
+ install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 uninstall-man3 uninstall-man5 \
+ uninstall-man8
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = man
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am: install-man
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-man
+uninstall: uninstall-recursive
+all-am: Makefile $(MANS)
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man3 \
+ $(DESTDIR)$(mandir)/man5 $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-man1 uninstall-man1 install-man3 uninstall-man3 \
+install-man5 uninstall-man5 install-man8 uninstall-man8 install-man \
+uninstall-man install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/man/chage.1 b/current/man/chage.1
new file mode 100644
index 00000000..2c09fc72
--- /dev/null
+++ b/current/man/chage.1
@@ -0,0 +1,109 @@
+.\" Copyright 1990 - 1994 Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: chage.1,v 1.6 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH CHAGE 1
+.SH NAME
+chage \- change user password expiry information
+.SH SYNOPSIS
+.TP 6
+\fBchage\fR
+[\fB-m \fImindays\fR] [\fB-M \fImaxdays\fR]
+[\fB-d \fIlastday\fR] [\fB-I \fIinactive\fR]
+.br
+[\fB-E \fIexpiredate\fR] [\fB-W \fIwarndays\fR] \fIuser\fR
+.TP 6
+\fBchage\fR
+\fB-l\fR \fIuser\fR
+.SH DESCRIPTION
+\fBchage\fR changes the number of days between password changes and the
+date of the last password change.
+This information is used by the system to determine when a user must
+change her password.
+The \fBchage\fR command is restricted to the root user, except for the
+\fB-l\fR option, which may be used by an unprivileged user to determine
+when her password or account is due to expire.
+.PP
+With the \fB-m\fR option, the value of \fImindays\fR is the minimum number
+of days between password changes.
+A value of zero for this field indicates that the user may change
+her password at any time.
+.PP
+With the \fB-M\fR option, the value of \fImaxdays\fR is the maximum number
+of days during which a password is valid.
+When \fImaxdays\fR plus \fIlastday\fR is less than the current day,
+the user will be required to change her password before being
+able to use her account.
+This occurance can be planned for in advance by use of the \fB-W\fR option,
+which provides the user with advance warning.
+.PP
+With the \fB-d\fR option, the value of \fIlastday\fR is the number of days
+since January 1st, 1970 when the password was last changed.
+The date may also be expressed in the format YYYY-MM-DD (or the format more
+commonly used in your area).
+.PP
+The \fB-E\fR option is used to set a date on which the user's account will
+no longer be accessible.
+The \fIexpiredate\fR option is the number of days since January 1, 1970 on
+which the accounted is locked.
+The date may also be expressed in the format YYYY-MM-DD (or the format more
+commonly used in your area).
+A user whose account is locked must contact the system administrator before
+being able to use the system again.
+.PP
+The \fB-I\fR option is used to set the number of days of inactivity after
+a password has expired before the account is locked.
+A user whose account is locked must contact the system administrator before
+being able to use the system again.
+The \fIinactive\fR option is the number of days of inactivity. A value of
+0 disables this feature.
+.PP
+The \fB-W\fR option is used to set the number of days of warning before a
+password change is required.
+The \fIwarndays\fR option is the number of days prior to the password
+expiring that a user will be warned her password is about to expire.
+.PP
+All of the above values are stored exactly as days when the shadow
+password file is used, but are converted to and from weeks when the
+standard password file is used.
+Because of this conversion, rounding errors may result.
+.PP
+If none of the options are selected, \fBchage\fR operates in an interactive
+fashion, prompting the user with the current values for all of the fields.
+Enter the new value to change the field, or leave the line blank to use
+the current value.
+The current value is displayed between a pair of \fB[ ]\fR marks.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- shadow user account information
+.SH SEE ALSO
+.BR passwd (5),
+.BR shadow (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/chfn.1 b/current/man/chfn.1
new file mode 100644
index 00000000..e0ae8828
--- /dev/null
+++ b/current/man/chfn.1
@@ -0,0 +1,66 @@
+.\" Copyright 1990 - 1994 Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: chfn.1,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH CHFN 1
+.SH NAME
+chfn \- change user name and information
+.SH SYNOPSIS
+.TP 5
+\fBchfn\fR
+[\fB-f \fIfull_name\fR] [\fB-r \fIroom_no\fR]
+.br
+[\fB-w \fIwork_ph\fR] [\fB-h \fIhome_ph\fR] [\fB-o \fIother\fR]
+[\fIuser\fR]
+.SH DESCRIPTION
+\fBchfn\fR changes user fullname, office number, office extension, and home
+phone number information for a user's account.
+This information is typically printed by \fBfinger\fR(1) and similiar
+programs.
+A normal user may only change the fields for their own account,
+the super user may change the fields for any account.
+Also, only the super user may use the \fB-o\fR option to change the
+undefined portions of the GCOS field.
+.PP
+The only restrictions placed on the contents of the fields is that no
+control characters may be present, nor any of comma, colon, or equal sign.
+The \fIother\fR field does not have this restriction, and is used to
+store accounting information used by other applications.
+.PP
+If none of the options are selected, \fBchfn\fR operates in an interactive
+fashion, prompting the user with the current values for all of the fields.
+Enter the new value to change the field, or leave the line blank to use
+the current value.
+The current value is displayed between a pair of \fB[ ]\fR marks.
+Without options, chfn prompts for the current user account.
+.SH FILES
+/etc/passwd \- user account information
+.SH SEE ALSO
+.BR passwd (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/chpasswd.8 b/current/man/chpasswd.8
new file mode 100644
index 00000000..860a1cdc
--- /dev/null
+++ b/current/man/chpasswd.8
@@ -0,0 +1,62 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: chpasswd.8,v 1.6 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH CHPASSWD 8
+.SH NAME
+\fBchpasswd\fR - update password file in batch
+.SH SYNOPSIS
+\fBchpasswd [-e]\fR
+.SH DESCRIPTION
+\fBchpasswd\fR reads a file of user name and password pairs
+from standard input and uses this information
+to update a group of existing users. Without the -e switch, the
+passwords are expected to be cleartext. With the -e switch, the
+passwords are expected to be in encrypted form.
+Each line is of the format
+.sp 1
+ \fIuser_name\fR:\fIpassword\fR
+.sp 1
+The named user must exist.
+The supplied password will be encrypted as necessary, and the password age
+updated, if present.
+.PP
+This command is intended to be used in a large system environment where
+many accounts are created at a single time.
+.SH CAVEATS
+.\" The \fBmkpasswd\fR command must be executed afterwards to update the
+.\" DBM password files.
+The input file must be protected if it contains unencrypted passwords.
+.\" This command may be discarded in favor of the newusers(8) command.
+.SH SEE ALSO
+.\" mkpasswd(8), passwd(1), useradd(1)
+.BR passwd (1),
+.BR useradd (8),
+.BR newusers (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/chsh.1 b/current/man/chsh.1
new file mode 100644
index 00000000..c2c1ee3e
--- /dev/null
+++ b/current/man/chsh.1
@@ -0,0 +1,66 @@
+.\" Copyright 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: chsh.1,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH CHSH 1
+.SH NAME
+chsh \- change login shell
+.SH SYNOPSIS
+.TP 5
+\fBchsh\fR
+[\fB-s \fIlogin_shell\fR] [\fIuser\fR]
+.SH DESCRIPTION
+\fBchsh\fR changes the user login shell.
+This determines the name of the user's initial login command.
+A normal user may only change the login shell for their own account,
+the super user may change the login shell for any account.
+.PP
+The only restrictions placed on the login shell is that the
+command name must be listed in \fI/etc/shells\fR, unless the
+invoker is the super-user, and then any value may be added.
+An account with a restricted login shell may not change
+their login shell.
+For this reason, placing \fB/bin/rsh\fR in \fI/etc/shells\fR
+is discouraged since accidentally changing to a restricted
+shell would prevent the user from every changing their login
+shell back to its original value.
+.PP
+If the \fB-s\fR option is not selected, \fBchsh\fR operates in an interactive
+fashion, prompting the user with the current login shell.
+Enter the new value to change the field, or leave the line blank to use
+the current value.
+The current value is displayed between a pair of \fB[ ]\fR marks.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shells \- list of valid login shells
+.SH SEE ALSO
+.BR chfn (1),
+.BR passwd (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/dialups.5 b/current/man/dialups.5
new file mode 100644
index 00000000..df33d6cd
--- /dev/null
+++ b/current/man/dialups.5
@@ -0,0 +1,22 @@
+.TH DIALUPS 5 "03 Oct 1999"
+.SH NAME
+d_passwd \- The dialup shell password file
+.br
+dialups \- List of dialup lines
+.SH DESCRIPTION
+The \fBd_passwd\fR file contains the names of login shells which require
+dialup passwords. Each line contains the fully qualified path name
+for the shell, followed by an optional password. Each field is separated
+by a '\fB:\fR'.
+.PP
+The \fBdialups\fR file contains the names of ports which may be dialup
+lines. Each line consists of the last component of the path name. The
+leading "\fB/dev/\fR" string is removed.
+.SH FILES
+/etc/d_passwd \- dialup shell password file
+.br
+/etc/dialups \- dialup line list
+.SH SEE ALSO
+.BR login (1),
+.SH AUTHOR
+Ben Collins <bcollins@debian.org>
diff --git a/current/man/dpasswd.8 b/current/man/dpasswd.8
new file mode 100644
index 00000000..b19b36f8
--- /dev/null
+++ b/current/man/dpasswd.8
@@ -0,0 +1,55 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: dpasswd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH DPASSWD 8
+.SH NAME
+\fBdpasswd\fR - change dialup password
+.SH SYNOPSIS
+\fBdpasswd\fR
+.RB [ - ( a | d )]
+\fIshell\fR
+.SH DESCRIPTION
+\fBdpasswd\fR adds, deletes, and updates dialup passwords for user
+login shells.
+The dialup password is prompted for after a user's password has been
+authenticated whenever the user logs in over a dialup line.
+\fBdpasswd\fR will prompt for the new password twice to insure it
+has been entered correctly.
+.PP
+The \fIshell\fR argument must be the complete pathname of the login
+program.
+.SH FILES
+.br
+/etc/d_passwd
+.br
+/etc/dialups
+.SH SEE ALSO
+.BR login (1)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/faillog.5 b/current/man/faillog.5
new file mode 100644
index 00000000..8beffdf9
--- /dev/null
+++ b/current/man/faillog.5
@@ -0,0 +1,59 @@
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: faillog.5,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH FAILLOG 5
+.SH NAME
+faillog \- Login failure logging file
+.SH DESCRIPTION
+.I faillog
+maintains a count of login failures and the limits for each account.
+The file is fixed length record, indexed by numerical UID.
+Each record contains the count of login failures since the last
+successful login;
+the maximum number of failures before the account is disabled;
+the line the last login failure occured on;
+and the date the last login failure occured.
+.PP
+The structure of the file is
+.DS
+
+ struct faillog {
+ short fail_cnt;
+ short fail_max;
+ char fail_line[12];
+ time_t fail_time;
+ };
+
+.DE
+.SH FILES
+/var/log/faillog \- login failure log
+.SH SEE ALSO
+.BR faillog (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/faillog.8 b/current/man/faillog.8
new file mode 100644
index 00000000..3ce76a1e
--- /dev/null
+++ b/current/man/faillog.8
@@ -0,0 +1,100 @@
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: faillog.8,v 1.7 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH FAILLOG 8
+.SH NAME
+faillog \- examine faillog and set login failure limits
+.SH SYNOPSIS
+.TP 8
+.B faillog
+.RB [ -u
+.IR login-name ]
+.RB [ -a ]
+.RB [ -t
+.IR days ]
+.RB [ -m
+.IR max ]
+.RB [ -pr ]
+.SH DESCRIPTION
+\fBfaillog\fR formats the contents of the failure log,
+\fI/var/log/faillog\fR, and maintains failure counts and
+limits.
+The order of the arguments to \fBfaillog\fR is significant.
+Each argument is processed immediately in the order given.
+.PP
+The \fB-p\fR flag causes failure entries to be printed in UID
+order.
+Entering \fB-u \fIlogin-name\fR flag will
+cause the failure record for \fIlogin-name\fR only to be printed.
+Entering \fB-t \fIdays\fR will cause only the
+failures more recent than \fIdays\fR to be printed.
+The \fB-t\fR flag overrides the use of \fB-u\fR.
+The \fB-a\fR flag causes all users to be selected.
+When used with the \fB-p\fR flag, this option selects all users
+who have ever had a login failure.
+It is meaningless with the \fB-r\fR flag.
+.PP
+The \fB-r\fR flag is used to reset the count of login failures.
+Write access to \fI/var/log/faillog\fR is required for
+this option.
+Entering \fB-u \fIlogin-name\fR will cause only the failure count
+for \fIlogin-name\fR to be reset.
+.PP
+The \fB-m\fR flag is used to set the maximum number of login
+failures before the account is disabled.
+Write access to \fI/var/log/faillog\fR is required for this
+option.
+Entering \fB-m \fImax\fR will cause all accounts to be disabled
+after \fImax\fR failed logins occur.
+This may be modified with \fB-u \fIlogin-name\fR to limit this
+function to \fIlogin-name\fR only.
+Selecting a \fImax\fR value of 0 has the effect of not placing
+a limit on the number of failed logins.
+The maximum failure count
+should always be 0 for \fBroot\fR to prevent
+a denial of services attack against the system.
+.PP
+Options may be combined in virtually any fashion.
+Each \fB-p\fR, \fB-r\fR, and \fB-m\fR option will cause
+immediate execution using any \fB-u\fR or \fB-t\fR modifier.
+.SH CAVEATS
+\fBfaillog\fR only prints out users with no successful login since
+the last failure.
+To print out a user who has had a successful login since their last
+failure, you must explicitly request the user with the \fB-u\fR flag,
+or print out all users with the \fB-a\fR flag.
+.PP
+Some systems may replace /var/log with /var/adm or /usr/adm.
+.SH FILES
+/var/log/faillog \- failure logging file
+.SH SEE ALSO
+.BR login (1),
+.BR faillog (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/gpasswd.1 b/current/man/gpasswd.1
new file mode 100644
index 00000000..2b9c3dfa
--- /dev/null
+++ b/current/man/gpasswd.1
@@ -0,0 +1,73 @@
+.\" Copyright 1996, Rafal Maszkowski, rzm@pdi.net
+.\" All rights reserved. You can redistribute this man page and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of the
+.\" License, or (at your option) any later version.
+.\"
+.\" $Id: gpasswd.1,v 1.2 1996/09/10 02:45:18 marekm Exp $
+.\"
+.TH GPASSWD 1
+.SH NAME
+gpasswd \- administer the /etc/group file
+.br
+.SH SYNOPSIS
+.B gpasswd \fIgroup\fR
+.br
+.B gpasswd
+.B -a
+\fIuser\fR \fIgroup\fR
+.br
+.B gpasswd
+.B -d
+\fIuser\fR \fIgroup\fR
+.br
+.B gpasswd
+.B -R
+\fIgroup\fR
+.br
+.B gpasswd
+.B -r
+\fIgroup\fR
+.br
+.B gpasswd
+.RB [ -A
+\fIuser\fR,...]
+.RB [ -M
+\fIuser\fR,...]
+\fIgroup\fR
+.br
+.SH DESCRIPTION
+.B gpasswd
+is used to administer the /etc/group file (and /etc/gshadow
+file if compiled with SHADOWGRP defined). Every group can
+have administrators, members and a password. System
+administrator can use \fB-A\fR option to define group
+administrator(s) and \fB-M\fR option to define members and
+has all rights of group administrators and members.
+.PP
+Group administrator can add and delete users using \fB-a\fR
+and \fB-d\fR options respectively. Administrators can use
+\fB-r\fR option to remove group password. When no password
+is set only group members can use
+.BR newgrp (1)
+to join the group. Option \fB-R\fR disables
+access to the group through
+.BR newgrp (1)
+command.
+.PP
+.B gpasswd
+called by a group administrator with group name only prompts
+for the group password. If password is set the members can still
+.BR newgrp (1)
+without a password, non-members must supply the password.
+
+.SH FILES
+/etc/group \- group information
+.br
+/etc/gshadow \- shadow group information
+.SH SEE ALSO
+.BR newgrp (1),
+.BR groupadd (8),
+.BR groupdel (8),
+.BR groupmod (8),
+.BR grpck (8)
diff --git a/current/man/groupadd.8 b/current/man/groupadd.8
new file mode 100644
index 00000000..2d3de403
--- /dev/null
+++ b/current/man/groupadd.8
@@ -0,0 +1,64 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groupadd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPADD 8
+.SH NAME
+groupadd \- Create a new group
+.SH SYNOPSIS
+.B groupadd
+[\fB-g\fI gid \fR[\fB-o\fR]]
+.I group
+.SH DESCRIPTION
+The \fBgroupadd\fR command
+creates a new group account using the values specified on the
+command line and the default values from the system.
+The new group will be entered into the system files as needed.
+The options which apply to the \fBgroupadd\fR command are
+.IP "\fB-g \fIgid\fR"
+The numerical value of the group's ID.
+This value must be unique, unless the \fB-o\fR option is used.
+The value must be non-negative.
+The default is to use the smallest ID value greater than 99 and
+greater than every other group.
+Values between 0 and 99 are typically reserved for system accounts.
+.SH FILES
+/etc/group \- group account information
+.br
+/etc/gshadow \- secure group account information
+.SH SEE ALSO
+.BR chfn (1),
+.BR chsh (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR passwd (1),
+.BR groupdel (8),
+.BR groupmod (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/groupdel.8 b/current/man/groupdel.8
new file mode 100644
index 00000000..19621a6b
--- /dev/null
+++ b/current/man/groupdel.8
@@ -0,0 +1,60 @@
+.\" Copyright 1991 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groupdel.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPDEL 8
+.SH NAME
+groupdel \- Delete a group
+.SH SYNOPSIS
+.B groupdel
+.I group
+.SH DESCRIPTION
+The \fBgroupdel\fR command modifies the system account files, deleting
+all entries that refer to \fIgroup\fR.
+The named group must exist.
+.PP
+You must manually check all filesystems to insure that no files remain
+with the named group as the file group ID.
+.SH CAVEATS
+You may not remove the primary group of any existing user.
+You must remove the user before you remove the group.
+.SH FILES
+/etc/group \- group information
+.br
+/etc/gshadow \- secure group information
+.SH SEE ALSO
+.BR chfn (1),
+.BR chsh (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR passwd (1),
+.BR groupadd (8),
+.BR groupmod (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/groupmod.8 b/current/man/groupmod.8
new file mode 100644
index 00000000..28815dc8
--- /dev/null
+++ b/current/man/groupmod.8
@@ -0,0 +1,66 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groupmod.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPMOD 8
+.SH NAME
+groupmod \- Modify a group
+.SH SYNOPSIS
+.B groupmod
+[\fB-g\fI gid \fR[\fB-o\fR]]
+[\fB-n\fI group_name \fR]
+.I group
+.SH DESCRIPTION
+The \fBgroupmod\fR command modifies the system account files to reflect
+the changes that are specified on the command line.
+The options which apply to the \fIgroupmod\fR command are
+.IP "\fB-g \fIgid\fR"
+The numerical value of the group's ID.
+This value must be unique, unless the \fB-o\fR option is used.
+The value must be non-negative.
+Values between 0 and 99 are typically reserved for system groups.
+Any files which the old group ID is the file group ID
+must have the file group ID changed manually.
+.IP "\fB-n \fIgroup_name\fR"
+The name of the group will be changed from \fIgroup\fR to
+\fIgroup_name\fR.
+.SH FILES
+/etc/group \- group information
+.br
+/etc/gshadow \- secure group information
+.SH SEE ALSO
+.BR chfn (1),
+.BR chsh (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR passwd (1),
+.BR groupadd (8),
+.BR groupdel (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/groups.1 b/current/man/groups.1
new file mode 100644
index 00000000..bae98989
--- /dev/null
+++ b/current/man/groups.1
@@ -0,0 +1,57 @@
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groups.1,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPS 1
+.SH NAME
+groups \- Display current group ID names
+.SH SYNOPSIS
+.B groups
+.RI [ user ]
+.SH DESCRIPTION
+.B groups
+displays the current group ID names
+or values.
+If the value does not have a corresponding entry in
+\fI/etc/group\fR, the value will be displayed as the numerical group value.
+The optional \fIuser\fR parameter will display the groups for the named
+\fIuser\fR.
+.SH NOTE
+Systems which do not support concurrent group sets will have the information
+from \fI/etc/group\fR reported.
+The user must use \fBnewgrp\fR or \fBsg\fR to change their current real and
+effective group ID.
+.SH FILES
+/etc/group \- group information
+.SH SEE ALSO
+.BR newgrp (1),
+.BR getuid (2),
+.BR getgid (2),
+.BR getgroups (2)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/grpck.8 b/current/man/grpck.8
new file mode 100644
index 00000000..3d2f7948
--- /dev/null
+++ b/current/man/grpck.8
@@ -0,0 +1,101 @@
+.\" Copyright 1992 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: grpck.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GRPCK 1
+.SH NAME
+grpck \- verify integrity of group files
+.SH SYNOPSIS
+\fBgrpck\fR [\fB-r\fR] [\fIgroup\fR \fIshadow\fR]
+.SH DESCRIPTION
+\fBgrpck\fR verifies the integrity of the system authentication information.
+All entries in the \fI/etc/group\fR and \fI/etc/gshadow\fR are checked to
+see that the entry has the proper format and valid data in each field.
+The user is prompted to delete entries that are improperly formatted or
+which have other incorrectable errors.
+.P
+Checks are made to verify that each entry has
+.sp
+.in +.5i
+- the correct number of fields
+.br
+- a unique group name
+.br
+- a valid list of members and administrators
+.in -.5i
+.sp
+.P
+The checks for correct number of fields and unique group name are fatal.
+If the entry has the wrong number of fields, the user will be prompted to
+delete the entire line.
+If the user does not answer affirmatively, all further checks are bypassed.
+An entry with a duplicated group name is prompted for deletion, but the
+remaining checks will still be made.
+All other errors are warnings and the user is encouraged to run the
+\fBgroupmod\fR command to correct the error.
+.P
+The commands which operate on the \fI/etc/group\fR file are not able to
+alter corrupted or duplicated entries.
+\fBgrpck\fR should be used in those circumstances to remove the offending
+entry.
+.SH OPTIONS
+By default, \fBgrpck\fR operates on the files \fI/etc/group\fR and
+\fI/etc/gshadow\fR.
+The user may select alternate files with the \fIgroup\fR and \fIshadow\fR
+parameters.
+Additionally, the user may execute the command in read-only mode by
+specifying the \fB-r\fR flag.
+This causes all questions regarding changes to be answered \fBno\fR
+without user intervention.
+.SH FILES
+/etc/group \- group account information
+.br
+/etc/gshadow \- encrypted passwords and group administrator information
+.br
+/etc/passwd \- user information
+.SH SEE ALSO
+.BR groupmod (8),
+.BR group (5),
+.BR passwd (5),
+.BR shadow (5)
+.SH DIAGNOSTICS
+The \fBgrpck\fR command exits with the following values:
+.IP 0 5
+Success
+.IP 1 5
+Syntax Error
+.IP 2 5
+One or more bad group entries
+.IP 3 5
+Cannot open group files
+.IP 4 5
+Cannot lock group files
+.IP 5 5
+Cannot update group files
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/id.1 b/current/man/id.1
new file mode 100644
index 00000000..19cf6a24
--- /dev/null
+++ b/current/man/id.1
@@ -0,0 +1,54 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: id.1,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH ID 1
+.SH NAME
+id \- Display current user and group ID names
+.SH SYNOPSIS
+.B id
+.RB [ -a ]
+.SH DESCRIPTION
+.B id
+displays the current real and effective user and group ID names
+or values.
+If the value does not have a corresponding entry in \fI/etc/passwd\fR
+or \fI/etc/group\fR, the value will be displayed without the corresponding
+name.
+The optional \fB-a\fR flag will display the group set on systems which
+support multiple concurrent group membership.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/group \- group information
+.SH SEE ALSO
+.BR getuid (2),
+.BR getgid (2),
+.BR getgroups (2)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/lastlog.8 b/current/man/lastlog.8
new file mode 100644
index 00000000..85acc13b
--- /dev/null
+++ b/current/man/lastlog.8
@@ -0,0 +1,63 @@
+.\" Copyright 1992, Phillip Street and Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)lastlog.8 3.3 08:24:58 29 Sep 1993 (National Guard Release)
+.\" $Id: lastlog.8,v 1.6 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH LASTLOG 8
+.SH NAME
+lastlog \- examine lastlog file
+.SH SYNOPSIS
+.B lastlog
+.RB [ -u
+.IR login-name ]
+.RB [ -t
+.IR days ]
+.SH DESCRIPTION
+\fBlastlog\fR formats and prints the contents of the last login log,
+\fI/var/log/lastlog\fR. The \fBlogin-name\fR, \fBport\fR, and \fBlast login
+time\fR will be printed.
+The default (no flags) causes lastlog entries to be printed, sorted
+by the numerical UID.
+Entering \fB-u \fIlogin-name\fR flag will
+cause the lastlog record for \fIlogin-name\fR only to be printed.
+Entering \fB-t \fIdays\fR will cause only the
+lastlogins more recent than \fIdays\fR to be printed.
+The \fB-t\fR flag overrides the use of \fB-u\fR.
+.PP
+If the user has never logged in the message \fB"**Never logged in**"\fR will
+be displayed instead of the port and time.
+.SH FILES
+/var/log/lastlog \- lastlog logging file
+.SH CAVEATS
+Large gaps in uid numbers will cause the lastlog program to run longer with
+no output to the screen (i.e. if mmdf=800 and last uid=170, program will
+appear to hang as it processes uid 171-799).
+.SH AUTHORS
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.br
+Phillip Street
diff --git a/current/man/limits.5 b/current/man/limits.5
new file mode 100644
index 00000000..4031219c
--- /dev/null
+++ b/current/man/limits.5
@@ -0,0 +1,76 @@
+.TH LIMITS 5
+.SH NAME
+limits \- Resource limits definition
+.SH DESCRIPTION
+The
+.I limits
+file (/etc/limits by default or LIMITS_FILE defined config.h)
+describes the resource limits you wish to impose.
+It should be owned by root and readable by root account only.
+.PP
+By default no quotas are imposed on 'root'. In fact, there is no way to impose
+limits via this procedure to root-equiv accounts (accounts with UID 0).
+.PP
+Each line describes a limit for a user in the form:
+.sp
+.I user LIMITS_STRING
+.PP
+The \fBLIMITS_STRING\fP is a string of a concatenated list of resource limits.
+Each limit consists of a letter identifier followed by a numerical limit.
+.PP
+The valid identifiers are:
+.sp
+A: max address space (KB)
+.br
+C: max core file size (KB)
+.br
+D: max data size (KB)
+.br
+F: maximum filesize (KB)
+.br
+M: max locked-in-memory address space (KB)
+.br
+N: max number of open files
+.br
+R: max resident set size (KB)
+.br
+S: max stack size (KB)
+.br
+T: max CPU time (MIN)
+.br
+U: max number of processes
+.br
+K: file creation mask, set by \fBumask\fR(2).
+.br
+L: max number of logins for this user
+.br
+P: process priority, set by \fBsetpriority\fR(2).
+.PP
+For example, \fIL2D2048N5\fP is a valid \fBLIMITS_STRING\fP. For reading convenience,
+the following entries are equivalent:
+.sp
+username L2D2048N5
+.br
+username L2 D2048 N5
+.PP
+Be aware that after \fIusername\fP the rest of the line is considered a limit
+string, thus comments are not allowed. A invalid limits string will be
+rejected (not considered) by the login program.
+.PP
+The default entry is denoted by username "\fB*\fP". If you have multiple \fIdefault\fP
+entries in your \fBLIMITS_FILE\fP, then the last one will be used as the default
+entry.
+.PP
+To completely disable limits for a user, a single dash "\fB-\fP" will do.
+.PP
+Also, please note that all limit settings are set PER LOGIN. They are
+not global, nor are they permanent. Perhaps global limits will come, but
+for now this will have to do ;)
+.SH FILES
+/etc/limits
+.SH SEE ALSO
+.BR login (1),
+.BR setpriority (2),
+.BR setrlimit (2)
+.SH AUTHOR
+Cristian Gafton (gafton@sorosis.ro)
diff --git a/current/man/login.1 b/current/man/login.1
new file mode 100644
index 00000000..45a42b5f
--- /dev/null
+++ b/current/man/login.1
@@ -0,0 +1,155 @@
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: login.1,v 1.7 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH LOGIN 1
+.SH NAME
+login \- Begin session on the system
+.SH SYNOPSIS
+\fBlogin\fR [\fB-p\fR] [\fIusername\fR] [\fIENV=VAR ...\fR]
+.br
+\fBlogin\fR [\fB-p\fR] [\fB-h\fR \fIhost\fR] [\fB-f\fR \fIusername\fR]
+.br
+\fBlogin\fR [\fB-p\fR] \fB-r\fR \fIhost\fR
+.SH DESCRIPTION
+.B login
+is used to establish a new session with the system.
+It is normally invoked automatically by responding to the
+.I login:
+prompt on the user\'s terminal.
+.B login
+may be special to the shell and may not be invoked as a sub-process.
+Typically,
+.B login
+is treated by the shell as \fBexec login\fR which causes the user
+to exit from the current shell.
+Attempting to execute \fBlogin\fR from any shell but the login shell
+will produce an error message.
+.PP
+When invoked from the \fIlogin:\fR prompt, the user may enter
+environmental variables after the username.
+These variables are entered in the form \fBNAME=VALUE\fR.
+Not all variables may be set in the fashion, notably \fBPATH\fR,
+\fBHOME\fR and \fBSHELL\fR.
+Additionally, \fBIFS\fR may be inhibited if the user\'s login
+shell is \fB/bin/sh\fR.
+.PP
+The user is then prompted for a password, where appropriate.
+Echoing is disabled to prevent revealing the password.
+Only a small number of password failures are permitted before
+\fBlogin\fR exits and the communications link is severed.
+.PP
+If password aging has been enabled for your account, you may be
+prompted for a new password before proceeding.
+You will be forced to provide your old password and the new
+password before continuing.
+Please refer to \fBpasswd \fR(1) for more information.
+.PP
+After a successful login,
+you will be informed of any system messages and the presence
+of mail.
+You may turn off the printing of the system message file,
+\fI/etc/motd\fR, by creating a zero-length file \fI.hushlogin\fR
+in your login directory.
+The mail message will be one of "\fBYou have new mail.\fR",
+"\fBYou have mail.\fR", or "\fBNo Mail.\fR" according to
+the condition of your mailbox.
+.PP
+Your user and group ID will be set according to their values in
+the \fI/etc/passwd\fR file.
+The value for \fB$HOME\fR, \fB$SHELL\fR, \fB$PATH\fR, \fB$LOGNAME\fR,
+and \fB$MAIL\fR are set according to the appropriate fields in the
+password entry.
+Ulimit, umask and nice values may also be set according to
+entries in the GECOS field.
+.PP
+On some installations, the environmental variable \fB$TERM\fR will be
+initialize to the terminal type on your tty line, as specified in
+\fI/etc/ttytype\fR.
+.PP
+An initialization script for your command interpreter may also be
+executed.
+Please see the appropriate manual section for more information on
+this function.
+.PP
+A subsystem login is indicated by the presense of a "*" as the first
+character of the login shell. The given home directory will be used as
+the root of a new filesystem which the user is actually logged into.
+.SH OPTIONS
+.TP
+.B -p
+Preserve environment.
+.TP
+.B -f
+Do not perform authentication, user is preauthenticated.
+.TP
+.B -h
+Name of the remote host for this login.
+.TP
+.B -r
+Perform autologin protocol for rlogin.
+.PP
+The \fB-r -h\fP and \fB-f\fP options are only used when \fBlogin\fP is invoked by root.
+.SH CAVEATS
+.PP
+This version of \fBlogin\fR has many compilation options, only some of which
+may be in use at any particular site.
+.PP
+The location of files is subject to differences in system configuration.
+.SH FILES
+/etc/utmp \- list of current login sessions
+.br
+/etc/wtmp \- list of previous login sessions
+.br
+/etc/passwd \- user account information
+.br
+/etc/shadow \- encrypted passwords and age information
+.br
+/etc/motd \- system message file
+.br
+/etc/nologin \- prevent non-root users from logging in
+.br
+/etc/ttytype \- list of terminal types
+.br
+$HOME/.profile \- initialization script for default shell
+.br
+$HOME/.hushlogin \- suppress printing of system messages
+.br
+.SH SEE ALSO
+.PP
+.BR getty (8),
+.BR mail (1),
+.BR passwd (1),
+.BR sh (1),
+.BR su (1),
+.BR login.defs (5),
+.\" .BR d_passwd (5),
+.BR passwd (5),
+.BR nologin (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/login.access.5 b/current/man/login.access.5
new file mode 100644
index 00000000..01f06beb
--- /dev/null
+++ b/current/man/login.access.5
@@ -0,0 +1,52 @@
+.\" this is comment
+.TH LOGIN.ACCESS 5
+.\" .Dt SKEY.ACCESS 5
+.\" .Os FreeBSD 1.2
+.SH NAME
+login.access \- Login access control table
+.SH DESCRIPTION
+The
+.I login.access
+file specifies (user, host) combinations and/or (user, tty)
+combinations for which a login will be either accepted or refused.
+.PP
+When someone logs in, the
+.I login.access
+is scanned for the first entry that
+matches the (user, host) combination, or, in case of non-networked
+logins, the first entry that matches the (user, tty) combination. The
+permissions field of that table entry determines whether the login will
+be accepted or refused.
+.PP
+Each line of the login access control table has three fields separated by a
+":" character:
+.sp 1
+.IR permission : users : origins
+.sp 1
+The first field should be a "\fB+\fR" (access granted) or "\fB-\fR"
+(access denied) character. The second field should be a list of one or
+more login names, group names, or
+.B ALL
+(always matches). The third field should be a list
+of one or more tty names (for non-networked logins), host names, domain
+names (begin with "\fB.\fR"), host addresses, internet network numbers
+(end with "\fB.\fR"),
+.B ALL
+(always matches) or
+.B LOCAL
+(matches any string that does not contain a "\fB.\fR" character).
+If you run NIS you can use @netgroupname in host or user patterns.
+.PP
+The
+.B EXCEPT
+operator makes it possible to write very compact rules.
+.PP
+The group file is searched only when a name does not match that of the
+logged-in user. Only groups are matched in which users are explicitly
+listed: the program does not look at a user's primary group id value.
+.SH FILES
+/etc/login.access
+.SH SEE ALSO
+.BR login (1)
+.SH AUTHOR
+Guido van Rooij
diff --git a/current/man/login.defs.5 b/current/man/login.defs.5
new file mode 100644
index 00000000..d21a3cc9
--- /dev/null
+++ b/current/man/login.defs.5
@@ -0,0 +1,573 @@
+.\" Copyright 1991 - 1993, Julianne Frances Haugh and Chip Rosenthal
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: login.defs.5,v 1.7 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH LOGIN 5
+.SH NAME
+/etc/login.defs \- Login configuration
+.SH DESCRIPTION
+The
+.I /etc/login.defs
+file defines the site-specific configuration for the shadow login
+suite. This file is required. Absence of this file will not prevent
+system operation, but will probably result in undesirable operation.
+.PP
+This file is a readable text file, each line of the file describing
+one configuration parameter. The lines consist of a configuration
+name and value, seperated by whitespace. Blank lines and comment
+lines are ignored. Comments are introduced with a `#' pound sign and
+the pound sign must be the first non-white character of the line.
+.PP
+Parameter values may be of four types: strings, booleans, numbers,
+and long numbers. A string is comprised of any printable characters.
+A boolean should be either the value ``yes'' or ``no''. An undefined
+boolean parameter or one with a value other than these will be given
+a ``no'' value. Numbers (both regular and long) may be either decimal
+values, octal values (precede the value with ``0'') or hexadecimal
+values (precede the value with ``0x''). The maximum value of the
+regular and long numeric parameters is machine-dependant.
+.PP
+The following configuration items are provided:
+.\"
+.IP "CHFN_AUTH (boolean)"
+If
+.IR yes ,
+the
+.B chfn
+and
+.B chsh
+programs will ask for password before making any changes, unless
+run by the superuser.
+.\"
+.IP "CHFN_RESTRICT (string)"
+This parameter specifies which values in the
+.I gecos
+field of the
+.I passwd
+file may be changed by regular users using the
+.B chfn
+program. It can be any combination of letters
+.IR f ,
+.IR r ,
+.IR w ,
+.IR h ,
+for Full name, Room number, Work phone, and Home phone, respectively.
+If not specified, only the superuser can make any changes.
+.\"
+.IP "CLOSE_SESSIONS (boolean)"
+Enable pam_close_session() calling. When using normal (pam_unix.so)
+session handling modules, this is not needed. However with modules
+(such as kerberos or other persistent session models),
+.B login
+needs to fork and wait for the shell to exit, so that sessions can be
+cleaned up.
+.\"
+.IP "CONSOLE (string)"
+If specified, this definition provides for a restricted set of lines
+on which root logins will be allowed. An attempted root login which
+does not meet the criteria established here will be rejected. The
+value of this field may be one of two forms, either a fully-rooted
+pathname such as
+.sp
+.ft I
+ CONSOLE /etc/consoles
+.ft R
+.sp
+or a colon-delimited list of terminal lines such as:
+.sp
+.ft I
+ CONSOLE console:tty01:tty02:tty03:tty04
+.ft R
+.sp
+If a pathname is given, each line of the file should specify one
+terminal line. If this parameter is not defined or the specified file
+does not exist, then root logins will be allowed from any terminal
+line. Because the removal of this file, or its truncation, could
+result in unauthorized root logins, this file must be protected.
+Where security is critical, the colon-separated form should be used
+to prevent this potential method of attack.
+.\"
+.IP "CONSOLE_GROUPS (string)"
+XXX needs to be documented.
+.\"
+.IP "CRACKLIB_DICTPATH (string)"
+XXX needs to be documented.
+.\"
+.IP "DEFAULT_HOME (boolean)"
+XXX needs to be documented.
+.\"
+.IP "DIALUPS_CHECK_ENAB (boolean)"
+If
+.I yes
+and an
+.I /etc/dialups
+file exists, then secondary passwords are enabled upon the dialup
+lines specified in this file. This file should contain a list of
+dialups, one per line, for example:
+.nf
+.sp
+.ft I
+ ttyfm01
+ ttyfm02
+ \0\0.
+ \0\0.
+ \0\0.
+.ft R
+.sp
+.fi
+.\"
+.IP "ENVIRON_FILE (string)"
+File containing a list of environment variables (one per line) to set
+when logging in or su'ing.
+.\"
+.IP "ENV_HZ (string)"
+This parameter specifies a value for an HZ environment parameter.
+Example usage is:
+.sp
+ \fIENV_HZ HZ=50\fR
+.sp
+If this parameter is not defined then no HZ value will be established.
+.\"
+.IP "ENV_PATH (string)"
+This parameter must be defined as the search path for regular users.
+When a login with UID other than zero occurs, the PATH environment
+parameter is initialized to this value. This parameter is required;
+if undefined a possibly incorrect default value will be provided.
+.\"
+.IP "ENV_SUPATH (string)"
+This parameter must be defined as the search path for the superuser.
+When a login with UID zero occurs, the PATH environment parameter is
+initialized to this value. This parameter is required; if undefined
+a possibly incorrect default value will be provided.
+.\"
+.IP "ENV_TZ (string)"
+This parameter specifies information for generating a TZ environment
+parameter. The value must either be the desired contents of TZ, or
+the full pathname of a file which contains this information. Example
+usage is:
+.sp
+ \fIENV_TZ\0\0\0\0TZ=CST6CDT\fP
+.sp
+or
+.sp
+ \fIENV_TZ\0\0\0\0/etc/tzname\fP
+.sp
+If a nonexistent file is named, then TZ will be initialized to some
+default value. If this parameter is not defined then no TZ value will
+be established.
+.\"
+.IP "ERASECHAR (number)"
+The terminal
+.I erase
+character is initialized to this value. This is supported only on
+systems with the
+.I termio
+interface, e.g. System V. If not specified, the erase character will
+be initialized to a backspace. See KILLCHAR for related information.
+.\"
+.IP "FAILLOG_ENAB (boolean)"
+If
+.I yes
+then login failures will be accumulated in
+.I /var/log/faillog
+in a
+.BR faillog (8)
+format.
+.\"
+.IP "FAIL_DELAY (number)"
+Delay time in seconds after each failed login attempt.
+.\"
+.IP "FAKE_SHELL (string)"
+Instead of the real user shell, the program specified by this
+parameter will be launched, although its visible name (argv[0]) will
+be the shell's. The program may do whatever it wants (logging,
+additional authentification, banner, ...) before running the actual
+shell.
+.\"
+.IP "FTMP_FILE (string)"
+This parameter specifies the full pathname to a file to which login
+failures are recorded. When a login failure occurs, a
+.I utmp
+format record will be appended to this file. Note that this differs
+from the
+.I /var/log/faillog
+failure logging in that this facility logs every failure whereas the
+``faillog'' facility accumulates failure information per user. If
+this parameter is not specified then logging will be inhibited. See
+FAILLOG_ENAB and LOG_UNKFAIL_ENAB for related information.
+.\"
+.IP "GID_MAX (number)"
+.IP "GID_MIN (number)"
+Range of group IDs to choose from for the
+.B groupadd
+program.
+.\"
+.IP "HUSHLOGIN_FILE (string)"
+This parameter is used to establish ``hushlogin'' conditions. There
+are two possible ways to establish these conditions. First, if the
+value of this parameter is a filename and that file exists in the
+user's home directory then ``hushlogin'' conditions will be in effect.
+The contents of this file are ignored; its mere presence triggers
+``hushlogin'' conditions. Second, if the value of this parameter is
+a full pathname and either the user's login name or the user's shell
+is found in this file, then ``hushlogin'' conditions will be in effect.
+In this case, the file should be in a format similar to:
+.nf
+.sp
+.ft I
+ demo
+ /usr/lib/uucp/uucico
+ \0\0.
+ \0\0.
+ \0\0.
+.ft R
+.sp
+.fi
+If this parameter is not defined, then ``hushlogin'' conditions will
+never occur. When ``hushlogin'' conditions are established, the
+message of the day, last successful and unsuccessful login display,
+mail status display, and password aging checks are suppressed. Note
+that allowing hushlogin files in user home directories allows the user
+to disable password aging checks. See MOTD_FILE, FAILLOG_ENAB,
+LASTLOG_ENAB, and MAIL_CHECK_ENAB for related information.
+.\"
+.IP "ISSUE_FILE (string)"
+Full pathname of the file to display before each login prompt.
+.\"
+.IP "KILLCHAR (number)"
+The terminal
+.I kill
+character is initialized to this value. This is supported only on
+systems with the
+.I termio
+interface, e.g. System V. If not specified, the kill character will
+be initialized to a \s-2CTRL/U\s0.
+See ERASECHAR for related information.
+.\"
+.IP "LASTLOG_ENAB (boolean)"
+If
+.IR yes ,
+and if the
+.I /var/log/lastlog
+file exists, then a successful user login will be recorded to this
+file. Furthermore, if this option is enabled then the times of the
+most recent successful and unsuccessful logins will be displayed to
+the user upon login. The unsuccessful login display will be suppressed
+if FAILLOG_ENAB is not enabled. If ``hushlogin'' conditions are in
+effect, then both the successful and unsuccessful login information
+will be suppressed.
+.\"
+.IP "LOGIN_RETRIES (number)"
+Number of login attempts allowed before the
+.B login
+program exits.
+.\"
+.IP "LOGIN_STRING (string)"
+XXX needs to be documented.
+.IP "LOGIN_TIMEOUT (number)"
+XXX needs to be documented.
+.IP "LOG_OK_LOGINS (boolean)"
+XXX needs to be documented.
+.IP "LOG_UNKFAIL_ENAB (boolean)"
+If
+.I yes
+then unknown usernames will be included when a login failure is
+recorded. Note that this is a potential security risk; a common login
+failure mode is transposition of the user name and password, thus this
+mode will often cause passwords to accumulate in the failure logs.
+If this option is disabled then unknown usernames will be suppressed
+in login failure messages.
+.\"
+.IP "MAIL_CHECK_ENAB (boolean)"
+If
+.IR yes ,
+the user will be notified of his or her mailbox status upon login.
+See MAIL_DIR for related information.
+.\"
+.IP "MAIL_DIR (string)"
+This parameter specifies the full pathname to the directory which
+contains the user mailbox files. The user's login name is appended
+to this path to form the MAIL environment parameter \- the path to
+the user's mailbox. Either this parameter or MAIL_FILE must be defined;
+if undefined some possibly incorrect default value will be assumed.
+See MAIL_CHECK_ENAB for related information.
+.\"
+.IP "MAIL_FILE (string)"
+This parameter specifies the name of the user's mailbox file. This
+name is appended to the name of the user's home directory to form the
+MAIL environment parameter \- the path to the user's mailbox. Either
+this parameter or MAIL_DIR must be defined; if undefined some possibly
+incorrect default value will be assumed. See MAIL_CHECK_ENAB for
+related information.
+.\"
+.IP "MD5_CRYPT_ENAB (boolean)"
+If
+.IR yes ,
+the
+.B passwd
+program will encrypt newly changed passwords using a new MD5-based
+.BR crypt (3)
+password hashing algorithm, which originally appeared in FreeBSD, and
+is also supported by libc-5.4.38 and glibc-2.0 (or higher) on Linux.
+This algorithm allows passwords longer than 8 characters (limited by
+.BR getpass (3)
+to 127 characters), but is incompatible with traditional
+.BR crypt (3)
+implementations.
+.\"
+.IP "MOTD_FILE (string)"
+This parameter specifies a colon-delimited list of pathnames to ``message
+of the day'' files.
+If a specified file exists, then its contents are displayed to the user
+upon login.
+If this parameter is not defined or ``hushlogin'' login conditions are
+in effect, this information will be suppressed.
+.\"
+.IP "NOLOGINS_FILE (string)"
+This parameter specifies the full pathname to a file which inhibits
+non-root logins. If this file exists and a user other than root
+attempts to log in, the contents of the file will be displayed and
+the user will be disconnected. If this parameter is not specified
+then this feature will be inhibited.
+.\"
+.IP "NOLOGIN_STR (string)"
+XXX needs to be documented.
+.\"
+.IP "OBSCURE_CHECKS_ENAB (boolean)"
+If
+.IR yes ,
+the
+.B passwd
+program will perform additional checks before accepting a password change.
+The checks performed are fairly simple, and their use is recommended.
+These obscurity checks are bypassed if
+.B passwd
+is run by
+.IR root .
+See PASS_MIN_LEN for related information.
+.\"
+.IP "PASS_ALWAYS_WARN (boolean)"
+XXX needs to be documented.
+.\"
+.IP "PASS_CHANGE_TRIES (number)"
+XXX needs to be documented.
+.\"
+.IP "PASS_MIN_DAYS (number)"
+The minimum number of days allowed between password changes. Any password
+changes attempted sooner than this will be rejected. If not specified, a
+zero value will be assumed.
+.\"
+.IP "PASS_MIN_LEN (number)"
+The minimum number of characters in an acceptable password. An attempt to
+assign a password with fewer characters will be rejected. A zero value
+suppresses this check. If not specified, a zero value will be assumed.
+.\"
+.IP "PASS_MAX_DAYS (number)"
+The maximum number of days a password may be used. If the password is
+older than this, then the account will be locked. If not specified,
+a large value will be assumed.
+.\"
+.IP "PASS_MAX_LEN (number)"
+XXX needs to be documented.
+.\"
+.IP "PASS_WARN_AGE (number)"
+The number of days warning given before a password expires. A zero means
+warning is given only upon the day of expiration, a negative value means
+no warning is given. If not specified, no warning will be provided.
+.\"
+.IP "PORTTIME_CHECKS_ENAB (boolean)"
+If
+.I yes
+and an
+.I /etc/porttime
+file exists, that file will be consulted to ensure the user may login
+at this time on the given line.
+c.f.
+.BR porttime (5)
+.\"
+.IP "QMAIL_DIR (string)"
+For Qmail users, this parameter specifies a directory where a Maildir
+hierarchy is stored.
+See MAIL_CHECK_ENAB for related information.
+.\"
+.IP "QUOTAS_ENAB (boolean)"
+If
+.I yes ,
+then the user's ``ulimit,'' ``umask,'' and ``niceness'' will be
+initialized to the values if specified in the
+.I gecos
+field of the
+.I passwd
+file.
+c.f.
+.BR passwd (5).
+.\"
+.IP "SU_NAME (string)"
+This parameter assigns a command name when ``su -'' is run. For
+example, if the parameter is defined as ``su'', then a
+.BR ps (1)
+listing would show the command running as ``-su''. If this parameter
+is undefined, then a
+.BR ps (1)
+listing would show the name of the actual shell being run, e.g.
+something like ``-sh''.
+.\"
+.IP "SULOG_FILE (string)"
+This parameter specifies a full pathname of a file in which
+.B su
+activity is logged.
+If this parameter is not specified, the logging is suppressed.
+Because the
+.B su
+command may be used when attempting to authenticate a password,
+either this option, or
+.I syslog
+should be used to note
+.B su
+activity. See the SYSLOG_SU_ENAB option for related information.
+.\"
+.IP "SU_WHEEL_ONLY (boolean)"
+XXX needs to be documented.
+.\"
+.IP "SYSLOG_SG_ENAB (boolean)"
+XXX needs to be documented.
+.\"
+.IP "SYSLOG_SU_ENAB (boolean)"
+If
+.I yes
+and
+.B login
+was compiled with
+.I syslog
+support, then all
+.B su
+activity will be noted through the
+.I syslog
+facility.
+See SULOG_FILE for related information.
+.\"
+.IP "TTYGROUP (string or number)"
+The group ownership of the terminal is initialized to this group
+name or number. One well-known security attack involves forcing terminal
+control sequences upon another user's terminal line. This problem
+can be averted by disabling permissions which allow other users to
+access the terminal line, but this unfortunately prevents programs
+such as
+.B write
+from operating. Another solution is to use a version of the
+.B write
+program which filters out potentially dangerous character sequences,
+make this program ``setgid'' to a special group, assign group ownership
+of the terminal line to this special group, and assign permissions of
+\fI0620\fR to the terminal line. The TTYGROUP definition has been
+provided for just this situation. If this item is not defined, then
+the group ownership of the terminal is initialized to the user's group
+number. See TTYPERMS for related information.
+.\"
+.IP "TTYPERM (number)"
+The login terminal permissions are initialized to this value. Typical
+values will be \fI0622\fR to permit others write access to the line
+or \fI0600\fR to secure the line from other users. If not specified,
+the terminal permissions will be initialized to \fI0622\fR. See
+TTYGROUP for related information.
+.\"
+.IP "TTYTYPE_FILE (string)"
+This parameter specifies the full pathname to a file which maps terminal
+lines to terminal types. Each line of the file contains a terminal
+type and a terminal line, seperated by whitespace, for example:
+.nf
+.sp
+.ft I
+ vt100\0 tty01
+ wyse60 tty02
+ \0\0.\0\0\0 \0\0.
+ \0\0.\0\0\0 \0\0.
+ \0\0.\0\0\0 \0\0.
+.ft R
+.sp
+.fi
+This information is only used to initialize the TERM environment parameter
+when it does not already exist.
+A line starting with a ``#'' pound sign will be treated as a comment.
+If this paramter is not specified, the file does not exist, or the terminal
+line is not found in the file, then the TERM environment parameter will not
+be set.
+.\"
+.IP "UID_MAX (number)"
+XXX needs to be documented.
+.IP "UID_MIN (number)"
+XXX needs to be documented.
+.\"
+.IP "ULIMIT (long number)"
+The file size limit is initialized to this value. This is supported
+only on systems with a
+.IR ulimit ,
+e.g. System V. If not specified, the file size limit will be initialized
+to some large value.
+.\"
+.IP "UMASK (number)"
+The permission mask is initialized to this value. If not specified,
+the permission mask will be initialized to zero.
+.\"
+.IP "USERDEL_CMD (string)"
+XXX needs to be documented.
+.\"
+.SH CROSS REFERENCE
+The following cross reference shows which programs in the shadow login
+suite use which parameters.
+.na
+.IP login 12
+CONSOLE DIALUPS_CHECK_ENAB ENV_HZ ENV_SUPATH ENV_TZ ERASECHAR FAILLOG_ENAB
+FTMP_FILE HUSHLOGIN_FILE KILLCHAR LASTLOG_ENAB LOG_UNKFAIL_ENAB
+MAIL_CHECK_ENAB MAIL_DIR MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB
+QUOTAS_ENAB TTYPERM TTYTYPE_FILE ULIMIT UMASK
+.IP newusers 12
+PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE UMASK
+.IP passwd 12
+OBSCURE_CHECKS_ENAB PASS_MIN_LEN
+.IP pwconv 12
+PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
+.IP su 12
+ENV_HZ ENV_SUPATH ENV_TZ HUSHLOGIN_FILE MAIL_CHECK_ENAB MAIL_DIR
+MOTD_FILE NOLOGIN_STR QUOTAS_ENAB SULOG_FILE SYSLOG_SU_ENAB
+.IP sulogin 12
+ENV_HZ ENV_SUPATH ENV_TZ MAIL_DIR QUOTAS_ENAB TTYPERM
+.ad
+.SH BUGS
+Some of the supported configuration parameters are not documented in this
+manual page.
+.SH SEE ALSO
+.BR login (1),
+.BR passwd (5),
+.BR faillog (5),
+.BR porttime (5),
+.BR faillog (8)
+.SH AUTHORS
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.br
+Chip Rosenthal (chip@unicom.com)
diff --git a/current/man/logoutd.8 b/current/man/logoutd.8
new file mode 100644
index 00000000..b611d4f9
--- /dev/null
+++ b/current/man/logoutd.8
@@ -0,0 +1,51 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: logoutd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH LOGOUTD 8
+.SH NAME
+logoutd \- Enforce login time restrictions
+.SH SYNOPSIS
+.B logoutd
+.SH DESCRIPTION
+.B logoutd
+enforces the login time and port restrictions specified in
+.IR /etc/porttime .
+.B logoutd
+should be started from \fI/etc/rc\fR.
+The \fI/etc/utmp\fR file is scanned periodically and each user name
+is checked to see if the named user is permitted on the named port
+at the current time.
+Any login session which is violating the restrictions in \fI/etc/porttime\fR
+is terminated.
+.SH FILES
+/etc/porttime \- login and port permissions
+.br
+/etc/utmp \- current login sessions
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/mkpasswd.8 b/current/man/mkpasswd.8
new file mode 100644
index 00000000..ad4ed796
--- /dev/null
+++ b/current/man/mkpasswd.8
@@ -0,0 +1,81 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: mkpasswd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH MKPASSWD 1
+.SH NAME
+mkpasswd \- Update passwd and group database files
+.SH SYNOPSIS
+\fBmkpasswd\fR [\fB-fvgps\fR] \fIfile\fR
+.SH DESCRIPTION
+.B mkpasswd
+reads the file in the format given by the flags and converts it to the
+corresponding database file format.
+These database files are used to improve access performance on systems
+with large numbers of users.
+The output files will be named \fIfile\fR.dir and \fIfile\fR.pag.
+.PP
+The \fB-f\fR option causes \fBmkpasswd\fR to ignore any existing output
+files and overwrite them.
+Normally \fBmkpasswd\fR complains about existing output files and quits.
+.PP
+The \fB-v\fR option causes \fBmkpasswd\fR to output information about
+each record as it is converted, with a final message at the very end.
+.PP
+The \fB-g\fR option treats the input file as though it were in
+\fI/etc/group\fR file format.
+When combined with the \fB-s\fR option, the \fI/etc/gshadow\fR file
+format is used instead.
+.PP
+The \fB-p\fR option treats the input file as though it were in
+\fI/etc/passwd\fR file format.
+This is the default.
+When combined with the \fB-s\fR option, the \fI/etc/shadow\fR file
+format is used instead.
+.SH CAVEATS
+The use of more than one database file is limited to systems which
+include the NDBM database library and therefore may not be available
+on every system.
+.SH NOTE
+Since most commands are capable of updating the database files as
+changes are made, this command need only be used when re-creating a
+deleted or corrupted database file.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- shadow user information
+.br
+/etc/group \- group information
+.br
+/etc/gshadow \- shadow group information
+.SH SEE ALSO
+.BR passwd (5),
+.BR group (5),
+.BR shadow (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/newgrp.1 b/current/man/newgrp.1
new file mode 100644
index 00000000..f3308357
--- /dev/null
+++ b/current/man/newgrp.1
@@ -0,0 +1,80 @@
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: newgrp.1,v 1.6 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH NEWGRP 1
+.SH NAME
+newgrp \- Change group ID
+.br
+sg \- Execute command as different group ID
+.SH SYNOPSIS
+.BR newgrp " [" - ]
+[\fIgroup\fR]
+.br
+.BR sg " [" - ]
+[\fIgroup\fR [[\fB-c\fR] \fIcommand\fR]]
+.SH DESCRIPTION
+.B newgrp
+is used to change the current group ID during a login session.
+If the optional \fB\-\fR flag is given, the user's environment
+will be reinitialized as though the user had logged in, otherwise
+the current environment, including current working directory,
+remains unchanged.
+.PP
+.B newgrp
+changes the current real group ID to the named group, or to
+the default group listed in \fI/etc/passwd\fR if no group name
+is given.
+The user will be prompted for a password if they do not have a
+password and the group does, or if the user is not listed as a
+member and the group has a password.
+The user will be denied access if the group password is empty
+and the user is not listed as a member.
+.PP
+The
+.B sg
+command works similiar to \fBnewgrp\fR but does not replace the
+user's shell, so upon exit from a \fBsg\fR command, you are
+returned to your previous group ID.
+.B sg
+also accepts a command.
+The command will be executed with the Bourne shell and must be
+enclosed in quotes.
+.SH CAVEATS
+This version of \fBnewgrp\fR has many compilation options,
+only some of which may be in use at any particular site.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/group \- group information
+.SH SEE ALSO
+.BR login (1),
+.BR id (1),
+.BR su (1)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/newusers.8 b/current/man/newusers.8
new file mode 100644
index 00000000..447b8d91
--- /dev/null
+++ b/current/man/newusers.8
@@ -0,0 +1,68 @@
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: newusers.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH NEWUSERS 8
+.SH NAME
+\fBnewusers\fR - update and create new users in batch
+.SH SYNOPSIS
+\fBnewusers\fR [\fI new_users \fR]
+.SH DESCRIPTION
+\fBnewusers\fR reads a file of user name and cleartext password pairs
+and uses this information to update a group of existing users or to
+create new users.
+Each line is in the same format as the standard password file (see
+\fBpasswd\fR(5)) with the following exceptions.
+.IP "\fIpw_passwd\fR" 10
+This field will be encrypted and used as the new value
+of the encrpted password.
+.IP "\fIpw_age\fR"
+This field will be ignored for shadow passwords if the user already
+exists.
+.IP "\fIpw_gid\fR"
+This field may be the name of an existing group, in which case the
+named user will be added as a member. If a non-existent numerical
+group is given, a new group will be created having this number.
+.IP "\fIpw_dir\fR"
+This field will be checked for existence as a directory and a new
+directory with the same name will be created if it does not already exist.
+The ownership of the directory will be set to be that of the user
+being created or updated.
+.PP
+This command is intended to be used in a large system environment where
+many accounts are updated at a single time.
+.SH CAVEATS
+.\" The \fImkpasswd\fR command must be executed afterwards to update the
+.\" DBM password files.
+The input file must be protected since it contains unencrypted passwords.
+.SH SEE ALSO
+.\" mkpasswd(8), passwd(1), useradd(1)
+.BR passwd (1),
+.BR useradd (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/passwd.1 b/current/man/passwd.1
new file mode 100644
index 00000000..8090db76
--- /dev/null
+++ b/current/man/passwd.1
@@ -0,0 +1,190 @@
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: passwd.1,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH PASSWD 1
+.SH NAME
+passwd \- change user password
+.SH SYNOPSIS
+\fBpasswd\fR [\fB-f\fR|\fB-s\fR] [\fIname\fR]
+.br
+\fBpasswd\fR [\fB-g\fR] [\fB-r\fR|\fBR\fR] \fIgroup\fR
+.br
+\fBpasswd\fR [\fB-x\fR \fImax\fR] [\fB-n\fR \fImin\fR]
+[\fB-w\fR \fIwarn\fR] [\fB-i\fR \fIinact\fR] \fIname\fR
+.br
+\fBpasswd\fR {\fB-l\fR|\fB-u\fR|\fB-d\fR|\fB-S\fR} \fIname\fR
+.SH DESCRIPTION
+\fBpasswd\fR changes passwords for user and group accounts.
+A normal user may only change the password for their own account,
+the super user may change the password for any account.
+The administrator of a group may change the password for the group.
+\fBpasswd\fR also changes account information, such as the full name
+of the user, their login shell, or password expiry dates and intervals.
+.SS Password Changes
+The user is first prompted for their old password,
+if one is present.
+This password is then encrypted and compared against the
+stored password.
+The user has only one chance to enter the correct password.
+The super user is permitted to bypass this step so that forgotten
+passwords may be changed.
+.PP
+After the password has been entered, password aging information
+is checked to see if the user is permitted to change their password
+at this time.
+If not, \fBpasswd\fR refuses to change the password and exits.
+.PP
+The user is then prompted for a replacement password.
+This password is tested for complexity.
+As a general guideline,
+passwords should consist of 6 to 8 characters including
+one or more from each of following sets:
+.IP "" .5i
+Lower case alphabetics
+.IP "" .5i
+Upper case alphabetics
+.IP "" .5i
+Digits 0 thru 9
+.IP "" .5i
+Punctuation marks
+.PP
+Care must be taken not to include the system default erase
+or kill characters.
+\fBpasswd\fR will reject any password which is not suitably
+complex.
+.PP
+If the password is accepted,
+\fBpasswd\fR will prompt again and compare the second entry
+against the first.
+Both entries are require to match in order for the password
+to be changed.
+.SS Group passwords
+When the \fB-g\fR option is used, the password for the named
+group is changed.
+The user must either be the super user, or a group administrator
+for the named group.
+The current group password is not prompted for.
+The \fB-r\fR option is used with the \fB-g\fR option to remove
+the current password from the named group.
+This allows group access to all members.
+The \fB-R\fR option is used with the \fB-g\fR option to restrict
+the named group for all users.
+.SS Password expiry information
+The password aging information may be changed by the super
+user with the \fB-x\fR, \fB-n\fR, \fB-w\fR, and \fB-i\fR options.
+The \fB-x\fR option is used to set the maximum number of days
+a password remains valid.
+After \fImax\fR days, the password is required to be changed.
+The \fB-n\fR option is used to set the minimum number of days
+before a password may be changed.
+The user will not be permitted to change the password until
+\fImin\fR days have elapsed.
+The \fB-w\fR option is used to set the number of days of warning
+the user will receive before their password will expire.
+The warning occurs \fIwarn\fR days before the expiration, telling
+the user how many days until the password is set to expire.
+The \fB-i\fR option is used to disable an account after the
+password has been expired for a number of days.
+After a user account has had an expired password for \fIinact\fR
+days, the user may no longer sign on to the account.
+.SS Account maintenance
+User accounts may be locked and unlocked with the \fB-l\fR and
+\fB-u\fR flags.
+The \fB-l\fR option disables an account by changing the password to a
+value which matches no possible encrypted value.
+The \fB-u\fR option re-enables an account by changing the password
+back to its previous value.
+.PP
+The account status may be given with the \fB-S\fR option.
+The status information consists of 6 parts.
+The first part indicates if the user account is locked (L), has no
+password (NP), or has a usable password (P).
+The second part gives the date of the last password change.
+The next four parts are the minimum age, maximum age, warning period,
+and inactivity period for the password.
+.SS Hints for user passwords
+The security of a password depends upon the strength of the
+encryption algorithm and the size of the key space.
+The \fB\s-2UNIX\s+2\fR System encryption method is based on
+the NBS DES algorithm and is very secure.
+The size of the key space depends upon the randomness of the
+password which is selected.
+.PP
+Compromises in password security normally result from careless
+password selection or handling.
+For this reason, you should select a password which does not
+appear in a dictionary or which must be written down.
+The password should also not be a proper name, your license
+number, birth date, or street address.
+Any of these may be used as guesses to violate system security.
+.PP
+Your password must easily remembered so that you will not
+be forced to write it on a piece of paper.
+This can be accomplished by appending two small words together
+and separating each with a special character or digit.
+For example, Pass%word.
+.PP
+Other methods of construction involve selecting an easily
+remembered phrase from literature and selecting the first
+or last letter from each.
+An example of this is
+.IP "" .5i
+Ask not for whom the bell tolls.
+.PP
+which produces
+.IP "" .5i
+An4wtbt.
+.PP
+You may be reasonably sure few crackers will have
+included this in their dictionary.
+You should, however, select your own methods for constructing
+passwords and not rely exclusively on the methods given here.
+.SS Notes about group passwords
+Group passwords are an inherent security problem since more
+than one person is permitted to know the password.
+However, groups are a useful tool for permitting co-operation
+between different users.
+.SH CAVEATS
+Not all options may be supported.
+Password complexity checking may vary from site to site.
+The user is urged to select as complex a password as they
+feel comfortable with.
+User's may not be able to change their password on a system if NIS
+is enabled and they are not logged into the NIS server.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- encrypted user passwords
+.SH SEE ALSO
+.BR passwd (3),
+.\" .BR shadow (3),
+.BR group (5),
+.BR passwd (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/passwd.5 b/current/man/passwd.5
new file mode 100644
index 00000000..3b21d092
--- /dev/null
+++ b/current/man/passwd.5
@@ -0,0 +1,111 @@
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: passwd.5,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH PASSWD 5
+.SH NAME
+passwd \- The password file
+.SH DESCRIPTION
+.I passwd
+contains various pieces of information for each user account.
+Included is
+.IP "" .5i
+Login name
+.IP "" .5i
+Optional encrypted password
+.IP "" .5i
+Numerical user ID
+.IP "" .5i
+Numerical group ID
+.IP "" .5i
+User name or comment field
+.IP "" .5i
+User home directory
+.IP "" .5i
+User command interpreter
+.PP
+The password field may not be filled if shadow passwords
+have been enabled.
+If shadow passwords are being used, the encrypted password will
+be found in \fI/etc/shadow\fR.
+The encryped password consists of 13 characters from the
+64 character alphabet
+a thru z, A thru Z, 0 thru 9, \. and /.
+Refer to \fBcrypt\fR(3) for details on how this string is
+interpreted.
+.PP
+An optional password age string may follow the encrypted
+password, separated by a comma, from the same alphabet
+as the password itself.
+The first character gives the number of weeks during which the
+password is valid.
+The second character gives the number of weeks which must pass
+before the user is permitted to change the password.
+The last two characters give the week since Jan 1970 when the
+password was last changed.
+When the number of weeks during which the password is valid
+have passed, the user will be required to provide a new
+password.
+.PP
+The comment field is used by various system utilities, such as
+\fBfinger\fR(1).
+Three additional values may be present in the comment field.
+They are
+.IP "" .5i
+pri= \- set initial value of nice
+.IP "" .5i
+umask= \- set initial value of umask
+.IP "" .5i
+ulimit= \- set initial value of ulimit
+.PP
+These fields are separated from each other and from any other
+comment field by a comma.
+.PP
+The home directory field provides the name of the initial
+working directory.
+\fBLogin\fR uses this information to set the value of
+the \fBHOME\fR environmental variable.
+.PP
+The command interpreter field provides the name of the user's
+command language interpreter, or the name of the initial program
+to execute.
+\fBLogin\fR uses this information to set the value of the
+\fBSHELL\fR environmental variable.
+If this field is empty, it defaults to the value \fB/bin/sh\fR.
+.SH FILES
+/etc/passwd \- user account information
+.SH SEE ALSO
+.BR login (1),
+.BR passwd (1),
+.BR su (1),
+.BR sulogin (8),
+.BR shadow (5),
+.BR pwconv (8),
+.BR pwunconv (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/Makefile.am b/current/man/pl/Makefile.am
new file mode 100644
index 00000000..2ef48e2c
--- /dev/null
+++ b/current/man/pl/Makefile.am
@@ -0,0 +1,60 @@
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+manpldir = $(mandir)/pl
+manpl1dir = $(manpldir)/man1
+manpl3dir = $(manpldir)/man3
+manpl5dir = $(manpldir)/man5
+manpl8dir = $(manpldir)/man8
+
+
+manpl1_DATA = \
+ chage.1 \
+ chfn.1 \
+ chsh.1 \
+ groups.1 \
+ gpasswd.1 \
+ id.1 \
+ login.1 \
+ newgrp.1 \
+ passwd.1 \
+ su.1
+
+manpl3_DATA = \
+ pw_auth.3 \
+ shadow.3
+
+manpl5_DATA = \
+ d_passwd.5 \
+ dialups.5 \
+ faillog.5 \
+ limits.5 \
+ login.access.5 \
+ login.defs.5 \
+ passwd.5 \
+ porttime.5 \
+ shadow.5 \
+ suauth.5
+
+manpl8_DATA = \
+ chpasswd.8 \
+ dpasswd.8 \
+ faillog.8 \
+ groupadd.8 \
+ groupdel.8 \
+ groupmod.8 \
+ grpck.8 \
+ lastlog.8 \
+ logoutd.8 \
+ mkpasswd.8 \
+ newusers.8 \
+ pwauth.8 \
+ pwck.8 \
+ pwconv.8 \
+ shadowconfig.8 \
+ sulogin.8
+ useradd.8 \
+ userdel.8 \
+ usermod.8 \
+ vipw.8
+
+EXTRA_DIST = $(manpl1_DATA) $(manpl3_DATA) $(manpl5_DATA) $(manpl8_DATA)
diff --git a/current/man/pl/Makefile.in b/current/man/pl/Makefile.in
new file mode 100644
index 00000000..277746be
--- /dev/null
+++ b/current/man/pl/Makefile.in
@@ -0,0 +1,316 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+manpldir = $(mandir)/pl
+manpl1dir = $(manpldir)/man1
+manpl3dir = $(manpldir)/man3
+manpl5dir = $(manpldir)/man5
+manpl8dir = $(manpldir)/man8
+
+manpl1_DATA = chage.1 chfn.1 chsh.1 groups.1 gpasswd.1 id.1 login.1 newgrp.1 passwd.1 su.1
+
+
+manpl3_DATA = pw_auth.3 shadow.3
+
+
+manpl5_DATA = d_passwd.5 dialups.5 faillog.5 limits.5 login.access.5 login.defs.5 passwd.5 porttime.5 shadow.5 suauth.5
+
+
+manpl8_DATA = chpasswd.8 dpasswd.8 faillog.8 groupadd.8 groupdel.8 groupmod.8 grpck.8 lastlog.8 logoutd.8 mkpasswd.8 newusers.8 pwauth.8 pwck.8 pwconv.8 shadowconfig.8 sulogin.8
+
+
+EXTRA_DIST = $(manpl1_DATA) $(manpl3_DATA) $(manpl5_DATA) $(manpl8_DATA)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES =
+DATA = $(manpl1_DATA) $(manpl3_DATA) $(manpl5_DATA) $(manpl8_DATA)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps man/pl/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+install-manpl1DATA: $(manpl1_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(manpl1dir)
+ @list='$(manpl1_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl1dir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl1dir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl1dir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(manpl1dir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-manpl1DATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(manpl1_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(manpl1dir)/$$p; \
+ done
+
+install-manpl3DATA: $(manpl3_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(manpl3dir)
+ @list='$(manpl3_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl3dir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl3dir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl3dir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(manpl3dir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-manpl3DATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(manpl3_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(manpl3dir)/$$p; \
+ done
+
+install-manpl5DATA: $(manpl5_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(manpl5dir)
+ @list='$(manpl5_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl5dir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl5dir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl5dir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(manpl5dir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-manpl5DATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(manpl5_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(manpl5dir)/$$p; \
+ done
+
+install-manpl8DATA: $(manpl8_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(manpl8dir)
+ @list='$(manpl8_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl8dir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl8dir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl8dir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(manpl8dir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-manpl8DATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(manpl8_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(manpl8dir)/$$p; \
+ done
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = man/pl
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am: install-manpl1DATA install-manpl3DATA \
+ install-manpl5DATA install-manpl8DATA
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-manpl1DATA uninstall-manpl3DATA \
+ uninstall-manpl5DATA uninstall-manpl8DATA
+uninstall: uninstall-am
+all-am: Makefile $(DATA)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(manpl1dir) $(DESTDIR)$(manpl3dir) \
+ $(DESTDIR)$(manpl5dir) $(DESTDIR)$(manpl8dir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: uninstall-manpl1DATA install-manpl1DATA uninstall-manpl3DATA \
+install-manpl3DATA uninstall-manpl5DATA install-manpl5DATA \
+uninstall-manpl8DATA install-manpl8DATA tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+ useradd.8 \
+ userdel.8 \
+ usermod.8 \
+ vipw.8
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/man/pl/chage.1 b/current/man/pl/chage.1
new file mode 100644
index 00000000..48f1c879
--- /dev/null
+++ b/current/man/pl/chage.1
@@ -0,0 +1,110 @@
+.\" {PTM/WK/1999-09-16}
+.\" Copyright 1990 - 1994 Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH CHAGE 1
+.SH NAZWA
+chage \- zmieñ informacjê o terminie wa¿no¶ci has³a u¿ytkownika
+.SH SK£ADNIA
+.TP 6
+.B chage
+.RB [ -m
+.IR mindni ]
+.RB [ -M
+.IR maxdni ]
+.RB [ -d
+.IR ostatni ]
+.RB [ -I
+.IR nieaktywne ]
+.br
+.RB [ -E
+.IR data_wa¿no¶ci ]
+.RB [ -W
+.IR dni_ostrzegania ]
+.I u¿ytkownik
+.TP 6
+.B chage -l \fIu¿ytkownik\fR
+.SH OPIS
+\fBchage\fR zmienia liczbê dni pomiêdzy zmianami has³a i datê ostatniej
+zmiany has³a. Informacjê tê system wykorzystuje do ustalenia, kiedy
+u¿ytkownik musi zmieniæ has³o.
+Polecenia \fBchage\fR mo¿e u¿yæ tylko u¿ytkownik root, za wyj±tkiem
+opcji \fB-l\fR. Mo¿e siê ni± pos³u¿yæ siê u¿ytkownik nieuprzywilejowany
+do stwierdzenia, kiedy wygasa jego w³asne has³o lub konto.
+.PP
+Opcja \fB-m\fR ustawia minimaln± liczbê dni pomiêdzy zmianami has³a
+na warto¶æ \fImindni\fR. Warto¶æ zerowa oznacza, ¿e u¿ytkownik mo¿e je zmieniaæ
+w dowolnym czasie.
+.PP
+Opcja \fB-M\fR ustawia maksymaln± liczbê dni, przez jakie has³o jest wa¿ne
+na warto¶æ \fImaxdni\fR.
+Gdy \fImaxdni\fR plus \fIostatni\fR jest mniejsze ni¿ bie¿±cy dzieñ,
+od u¿ytkownika wymagana jest zmiana has³a przed skorzystaniem z konta.
+Zdarzenie to mo¿e byæ zaplanowane z wyprzedzeniem przez wykorzystanie
+opcji \fB-W\fR, ostrzegaj±cej zawczasu u¿ytkownika o zbli¿aj±cym siê terminie
+zmiany.
+.PP
+Opcja \fB-d\fR ustawia liczbê dni od 1 stycznia 1970 do dnia kiedy ostatnio
+zmieniono has³o na \fIostatni\fR. Data mo¿e równie¿ zostaæ podana w postaci
+RRRR-MM-DD (lub postaci powszechniej u¿ywanej w twoim regionie).
+.PP
+Opcja \fB-E\fR s³u¿y do ustawiania daty, od której konto u¿ytkownika
+nie bêdzie ju¿ dostêpne.
+\fIdata_wa¿no¶ci\fR jest liczb± dni od 1 stycznia 1970, od której konto jest
+blokowane. Data mo¿e byæ te¿ wyra¿ona w postaci RRRR-MM-DD (lub innej,
+powszechniej u¿ywanej w twoim regionie).
+U¿ytkownik, którego konto jest zablokowane musi skontaktowaæ siê
+z administratorem systemu zanim bêdzie móg³ z niego ponownie skorzystaæ.
+.PP
+Opcja \fB-I\fR s³u¿y do ustawiania czasu nieaktywno¶ci po wyga¶niêciu
+has³a, po którym konto jest blokowane. Parametr \fInieaktywne\fR podaje
+liczbê dni nieaktywno¶ci. Warto¶æ 0 wy³±cza tê funkcjê.
+U¿ytkownik, którego konto jest zablokowane musi skontaktowaæ siê
+z administratorem systemu zanim bêdzie móg³ z niego ponownie skorzystaæ.
+.PP
+Opcja \fB-W\fR s³u¿y do ustawiania ostrzegania przed wymagan± zmian± has³a.
+Parametr \fIdni_ostrzegania\fR jest liczb± dni przed up³ywem wa¿no¶ci has³a;
+od tego dnia u¿ytkownik bêdzie ostrzegany o nadchodz±cym terminie.
+.PP
+Wszystkie powy¿sze warto¶ci przechowywane s± jako liczba dni, je¿eli u¿ywany
+jest dodatkowy, przes³aniany plik hase³ (shadow). Jednak je¿eli u¿ywany jest
+standardowy plik hase³, to s± one zamieniane (w obie strony) na liczbê tygodni.
+Z powodu powy¿szej konwersji mog± pojawiæ siê b³êdy zaokr±gleñ.
+.PP
+Je¶li nie podano ¿adnej opcji, to \fBchage\fR dzia³a w trybie interaktywnym,
+proponuj±c u¿ytkownikowi warto¶ci bie¿±ce dla ka¿dego z pól. Wprowad¼ now±
+warto¶æ by zmieniæ pole, lub pozostaw pust± by u¿yæ warto¶ci bie¿±cej.
+Bie¿±ca warto¶æ pola wy¶wietlana jest miêdzy par± znaczników \fB[ ]\fR.
+.SH PLIKI
+.IR /etc/passwd " - informacje o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - chronione informacje o kontach u¿ytkowników"
+.SH ZOBACZ TAK¯E
+.BR passwd (5),
+.BR shadow (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/chfn.1 b/current/man/pl/chfn.1
new file mode 100644
index 00000000..8b254764
--- /dev/null
+++ b/current/man/pl/chfn.1
@@ -0,0 +1,77 @@
+.\" {PTM/WK/1999-09-25}
+.\" Copyright 1990 - 1994 Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH CHFN 1
+.SH NAZWA
+chfn \- zmieñ nazwê u¿ytkownika i informacjê o nim
+.SH SK£ADNIA
+.TP 5
+.B chfn
+.RB [ -f
+.IR pe³na_nazwa ]
+.RB [ -r
+.IR nr_pokoju ]
+.br
+.RB [ -w
+.IR tel_s³u¿b ]
+.RB [ -h
+.IR tel_dom ]
+.RB [ -o
+.IR inne ]
+.RI [ u¿ytkownik ]
+.SH OPIS
+\fBchfn\fR zmienia pe³n± nazwê (imiê i nazwisko), telefon s³u¿bowy i domowy
+dla danego konta u¿ytkownika. Informacja ta jest zwykle drukowana przez
+\fBfinger\fR(1) i podobne mu programy.
+Zwyk³y u¿ytkownik mo¿e zmieniaæ wy³±cznie pola opisuj±ce w³asne konto.
+Tylko superu¿ytkownik mo¿e zmieniaæ pola dowolnego konta.
+Równie¿ tylko on mo¿e pos³u¿yæ siê opcj± \fB-o\fR by zmieniæ niezdefiniowane
+czê¶ci pola GECOS.
+.PP
+Jedynym ograniczeniem nak³adanym na zawarto¶æ pól jest zakaz u¿ywania w nich
+znaków kontrolnych oraz przecinka, dwukropka i znaku równo¶ci.
+Pola \fIinne\fR (other) nie obowi±zuje to ograniczenie. Pole to s³u¿y do
+przechowywania informacji rozliczeniowej u¿ywanej przez inne aplikacje.
+.PP
+Je¶li nie wybrano ¿adnej z opcji, to \fBchfn\fR dzia³a w trybie interaktywnym,
+proponuj±c u¿ytkownikowi warto¶ci bie¿±ce dla ka¿dego z pól. Wprowad¼ now±
+warto¶æ by zmieniæ pole, lub pozostaw pust± by u¿yæ warto¶ci bie¿±cej.
+Bie¿±ca warto¶æ pola wy¶wietlana jest miêdzy par± znaczników \fB[ ]\fR.
+Bez podania opcji \fBchfn\fR pyta o konto u¿ytkownika, które ma podlegaæ
+zmianie.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.SH ZOBACZ TAK¯E
+.BR passwd (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/chpasswd.8 b/current/man/pl/chpasswd.8
new file mode 100644
index 00000000..eea01899
--- /dev/null
+++ b/current/man/pl/chpasswd.8
@@ -0,0 +1,62 @@
+.\" {PTM/WK/1999-09-16}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH CHPASSWD 8
+.SH NAZWA
+chpasswd - wsadowa aktualizacja pliku hase³
+.SH SK£ADNIA
+.B chpasswd
+.RB [ -e ]
+.SH OPIS
+\fBchpasswd\fR odczytuje ze standardowego wej¶cia plik zawieraj±cy pary:
+nazwa u¿ytkownika i has³o. Odczytan± informacje wykorzystuje do aktualizacji
+grupy istniej±cych u¿ytkowników.
+Bez prze³±cznika -e, has³a traktowane s± jako podane jawnie. Z prze³±cznikiem
+-e has³a powinny byæ dostarczone w postaci zakodowanej (encrypted).
+Ka¿dy wiersz ma postaæ
+.sp 1
+ \fInazwa_U¿ytkownika\fR:\fIhas³o\fR
+.sp 1
+Dany u¿ytkownik musi istnieæ.
+Je¿eli bêdzie to konieczne, podane has³o zostanie zakodowane a wiek has³a,
+je¶li wystêpuje, zaktualizowany.
+.PP
+Polecenie to przeznaczone jest do u¿ytku w du¿ych systemach, gdzie aktualizuje
+siê wiele kont naraz.
+.SH PRZESTROGI
+.\" Po u¿yciu \fBchpasswd\fR musi zostaæ wykonane polecenie \fImkpasswd\fR,
+.\" aktualizuj±ce pliki DBM hase³ (DBM password files).
+Plik ¼ród³owy, je¶li zawiera niezakodowane has³a, musi byæ chroniony.
+.\" Polecenie to mo¿e byæ zaniechane na rzecz polecenia newusers(8).
+.SH ZOBACZ TAK¯E
+.\" mkpasswd(8), passwd(1), useradd(1)
+.BR passwd (1),
+.BR useradd (8),
+.BR newusers (8)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/chsh.1 b/current/man/pl/chsh.1
new file mode 100644
index 00000000..7f20e865
--- /dev/null
+++ b/current/man/pl/chsh.1
@@ -0,0 +1,70 @@
+.\" {PTM/WK/1999-09-25}
+.\" Copyright 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH CHSH 1
+.SH NAZWA
+chsh \- zmieñ pow³okê zg³oszeniow±
+.SH SK£ADNIA
+.TP 5
+.B chsh
+.RB [ -s
+.IR pow³oka ]
+.RI [ u¿ytkownik ]
+.SH OPIS
+\fBchsh\fR zmienia pow³okê zg³oszeniow± u¿ytkownika.
+Okre¶la nazwê pocz±tkowego polecenia zg³oszeniowego u¿ytkownika.
+Zwyk³y u¿ytkownik mo¿e zmieniæ wy³±cznie pow³okê zg³oszeniow± w³asnego konta,
+superu¿ytkownik mo¿e zmieniæ pow³okê zg³oszeniow± dla dowolnego konta.
+.PP
+Jedynym ograniczeniem na³o¿onym na pow³okê zg³oszeniow± jest to, ¿e jej nazwa
+musi byæ ujêta w \fI/etc/shells\fR, chyba ¿e polecenie \fBchsh\fR wywo³ywane
+jest przez superu¿ytkownika, wówczas mo¿e byæ podana nazwa dowolnego polecenia.
+U¿ytkownicy kont z ograniczon± pow³ok± logowania nie mog± jej zmieniaæ.
+Odradza siê z tego powodu umieszczanie \fB/bin/rsh\fR w pliku \fI/etc/shells\fR,
+gdy¿ przypadkowa zmiana na pow³okê ograniczon± uniemo¿liwi u¿ytkownikowi
+jak±kolwiek zmianê pow³oki logowania, nawet z powrotem na dotychczasow±.
+.PP
+je¿eli nie podano opcji \fB-s\fR, to \fBchsh\fR dzia³a w trybie interaktywnym,
+proponuj±c u¿ytkownikowi bie¿±c± pow³okê logowania. Wprowad¼ now± warto¶æ
+do pola lub pozostaw je puste, by pozostawiæ aktualn± warto¶æ.
+Bie¿±ca warto¶æ wy¶wietlana jest pomiêdzy par± znaczników \fB[ ]\fR.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shells " - lista dozwolonych pow³ok zg³oszeniowych"
+.SH ZOBACZ TAK¯E
+.BR chfn (1),
+.BR passwd (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Istnieje wiele programów i skryptów do zarz±dzania kontami
+u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij
+siê, ¿e korzystasz z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/d_passwd.5 b/current/man/pl/d_passwd.5
new file mode 100644
index 00000000..0b3989b2
--- /dev/null
+++ b/current/man/pl/d_passwd.5
@@ -0,0 +1,30 @@
+.\"
+.\" {PTM/WK/1999-09-22}
+.\"
+.TH D_PASSWD 5
+.SH NAZWA
+d_passwd - plik hase³ telefonicznych
+.SH OPIS
+Z dostêpem do systemu przez liniê telefoniczn± zwi±zane s± dwa pliki
+konfiguracyjne: \fI/etc/d_passwd\fR, zawieraj±cy has³a i \fI/etc/dialups\fR,
+zawieraj±cy linie.
+Ka¿dorazowo, zanim u¿ytkownik ³±cz±cy siê za po¶rednictwem modemu otrzyma
+dostêp do systemu, musi podaæ has³o telefoniczne. Has³a te s± niezale¿ne
+od hase³ u¿ytkowników i przypisane nie do u¿ytkownika, ani linii terminalowej,
+lecz do pow³oki zg³oszeniowej u¿ytkownika.
+Do rozpoczêcia sesji wymagane jest zarówno has³o u¿ytkownika jak
+i telefoniczne. Zauwa¿ jednak, ¿e has³a telefoniczne nie posiadaj± kontroli
+terminu wa¿no¶ci. Nale¿y, po uzgodnieniu, okresowo zmieniaæ je rêcznie.
+W pliku \fId_passwd\fR kolejne wiersze definiuj± has³a dla rozmaitych pow³ok:
+.br
+.sp 1
+ pow³oka:zakodowane_has³o:
+.br
+.sp 1
+Zauwa¿, ¿e po polu has³a wystêpuje dwukropek. Pow³oka powinna byæ
+okre¶lona przez bezwzglêdn± nazwê ¶cie¿kow± pliku interpretatora poleceñ.
+Do zarz±dzania has³ami telefonicznymi s³u¿y polecenie \fBdpasswd\fR (1).
+.SH ZOBACZ TAK¯E
+.BR dpasswd (1),
+.BR login (1),
+.BR dialups (5).
diff --git a/current/man/pl/dialups.5 b/current/man/pl/dialups.5
new file mode 100644
index 00000000..3edb8a2c
--- /dev/null
+++ b/current/man/pl/dialups.5
@@ -0,0 +1,24 @@
+.\"
+.\" {PTM/WK/1999-09-22}
+.\"
+.TH DIALUPS
+.SH NAZWA
+dialups - plik terminalowych linii telefonicznych
+.SH OPIS
+Z dostêpem do systemu przez liniê telefoniczn± zwi±zane s± dwa pliki
+konfiguracyjne: \fI/etc/d_passwd\fR, zawieraj±cy has³a i \fI/etc/dialups\fR,
+zawieraj±cy linie. W ka¿dym wierszu pliku \fIdialups\fR zawarta jest nazwa
+pliku specjalnego linii terminalowej, do której pod³±czony jest modem:
+.br
+.sp 1
+ /dev/tty12
+ /dev/tty13
+.br
+.sp 1
+Warto jest uj±æ w nim \fBwszystkie\fR linie z dostêpem modemowym.
+Po³±czenie z linii pominiêtej nie bêdzie dodatkowo weryfikowane - u¿ytkownicy
+³±cz±cy siê ni± nie bêd± musieli podawaæ has³a telefonicznego.
+.SH ZOBACZ TAK¯E
+.BR dpasswd (1),
+.BR login (1),
+.BR d_passwd (5).
diff --git a/current/man/pl/dpasswd.8 b/current/man/pl/dpasswd.8
new file mode 100644
index 00000000..b5cf5624
--- /dev/null
+++ b/current/man/pl/dpasswd.8
@@ -0,0 +1,56 @@
+.\" {PTM/WK/1999-09-17}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH DPASSWD 8
+.SH NAZWA
+\fBdpasswd\fR - zmieñ has³o telefoniczne
+.SH SK£ADNIA
+.B dpasswd
+.RB [ - ( a | d )]
+.I pow³oka
+.SH OPIS
+\fBdpasswd\fR dodaje, usuwa i aktualizuje has³a telefoniczne (dialup
+passwords) dla pow³ok logowania u¿ytkowników.
+Ka¿dorazowo, gdy u¿ytkownik loguje siê przez liniê telefoniczn±,
+¿±dane jest od niego has³o telefoniczne (po poprawnym uwierzytelnieniu
+jego w³asnego has³a).
+.PP
+\fBdpasswd\fR bêdzie prosiæ o podanie nowego has³a dwukrotnie, by upewniæ
+siê, ¿e zosta³o ono poprawnie wprowadzone.
+.PP
+Argument \fIpow³oka\fR musi byæ pe³n±, ¶cie¿kow± nazw± programu zg³oszenia
+(logowania).
+.SH PLIKI
+.br
+.I /etc/d_passwd
+.br
+.I /etc/dialups
+.SH ZOBACZ TAK¯E
+.BR login (1)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/faillog.5 b/current/man/pl/faillog.5
new file mode 100644
index 00000000..6fc16cdf
--- /dev/null
+++ b/current/man/pl/faillog.5
@@ -0,0 +1,59 @@
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Translation (c) 1998 "Gwidon S. Naskrent" <naskrent@hoth.amu.edu.pl>
+.\" $Id: faillog.5,v 1.3 1999/09/20 20:56:42 wojtek2 Exp $
+.\"
+.TH faillog 5
+.SH NAZWA
+faillog \- plik rejestruj±cy nieudane zalogowania
+.SH OPIS
+.I faillog
+prowadzi licznik nieudanych zalogowañ i limity dla ka¿dego konta.
+Plik ten sk³ada siê z rekordów o sta³ej d³ugo¶ci, indeksowanych
+liczbowym UID. Ka¿dy rekord zawiera licznik nieudanych zalogowañ
+od ostatniego pomy¶lnego logowania, maksymaln± liczbê pomy³ek
+przed zablokowaniem konta, konsolê na której nast±pi³o ostatnie
+nieudane logowanie, oraz datê tego¿.
+.PP
+Struktura tego pliku to
+.DS
+
+ struct faillog {
+ short fail_cnt;
+ short fail_max;
+ char fail_line[12];
+ time_t fail_time;
+ };
+
+.DE
+.SH PLIKI
+.IR /var/log/faillog " - rejestr nieudanych zalogowañ"
+.SH ZOBACZ TAK¯E
+.BR faillog (8)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/faillog.8 b/current/man/pl/faillog.8
new file mode 100644
index 00000000..a180cc4b
--- /dev/null
+++ b/current/man/pl/faillog.8
@@ -0,0 +1,95 @@
+.\" {PTM/WK/1999-09-18}
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH FAILLOG 8
+.SH NAZWA
+faillog \- sprawd¼ faillog i ustaw limity b³êdnych logowañ
+.SH SK£ADNIA
+.TP 8
+.B faillog
+.RB [ -u
+.IR nazwa ]
+.RB [ -a ]
+.RB [ -t
+.IR dni ]
+.RB [ -m
+.IR max ]
+.RB [ -pr ]
+.SH OPIS
+\fBfaillog\fR formatuje zawarto¶æ rejestru nieudanych prób rozpoczêcia sesji,
+\fI/var/log/faillog\fR, oraz obs³uguje ograniczenia i liczniki b³êdnych prób.
+Kolejno¶æ argumentów \fBfaillog\fR jest znacz±ca. Ka¿dy z argumentów jest
+natychmiast przetwarzany w zadanej kolejno¶ci.
+.PP
+Flaga \fB-p\fR powoduje, ¿e zapisy o nieudanych logowaniach wy¶wietlane bêd±
+w kolejno¶ci rosn±cych identyfikatorów u¿ytkowników (UID).
+Pos³u¿enie siê flag± \fB-u \fInazwa\fR spowoduje, ¿e zostanie wy¶wietlony
+wy³±cznie zapis dotycz±cy u¿ytkownika o tej \fInazwie\fR.
+U¿ycie \fB-t \fIdni\fR powoduje wy¶wietlanie wy³±cznie nieudanych prób
+logowania ¶wie¿szych ni¿ sprzed zadanej liczby \fIdni\fR.
+Flaga \fB-t\fR uniewa¿nia u¿ycie \fB-u\fR.
+Flaga \fB-a\fR powoduje wybranie wszystkich u¿ytkowników.
+W po³±czeniu z flag± \fB-p\fR flag, opcja ta wybiera wszystkich u¿ytkowników,
+dla których kiedykolwiek odnotowano niepomy¶ln± próbê logowania.
+Opcja ta nie ma znaczenia w po³±czeniu z flag± \fB-r\fR.
+.PP
+\fB-r\fR s³u¿y do zerowania licznika b³êdnych logowañ. Do poprawnego dzia³ania
+tej opcji wymagane jest prawo zapisu do \fI/var/log/faillog\fR.
+W po³±czeniu z \fB-u \fInazwa\fR s³u¿y do zerowania licznika b³êdów u¿ytkownika
+o podanej \fInazwie\fR.
+.PP
+Flaga \fB-m\fR ustawia maksymaln± liczbê b³êdów logowania, po której konto
+zostanie wy³±czone. Dla tej opcji wymagane jest prawo zapisu do
+\fI/var/log/faillog\fR.
+Argumenty \fB-m \fImax\fR powoduj±, ¿e wszystkie konta bêd± wy³±czane po
+\fImax\fR nieudanych próbach logowania.
+U¿ycie dodatkowo \fB-u \fInazwa\fR, ogranicza dzia³anie tej funkcji do
+u¿ytkownika o podanej \fInazwie\fR.
+Pos³u¿enie siê zerow± warto¶ci± \fImax\fR powoduje, ¿e liczba nieudanych prób
+rozpoczêcia sesji jest nieograniczona.
+Dla u¿ytkownika \fBroot\fR maksymalna liczba niepowodzeñ powinna byæ zawsze
+ustawiona na 0, by zapobiec atakom typu denial of service (odmowa obs³ugi).
+.PP
+Opcje mog± byæ ³±czone w praktycznie dowolny sposób. Ka¿da z opcji \fB-p\fR,
+\fB-r\fR i \fB-m\fR powoduje natychmiastowe wykonanie przy u¿yciu modyfikatora
+\fB-u\fR lub \fB-t\fR.
+.SH PRZESTROGI
+\fBfaillog\fR wy¶wietla wy³±cznie u¿ytkowników, którzy od ostatniej nieudanej
+próby nie mieli poprawnych logowañ.
+Chc±c wy¶wietliæ u¿ytkownika, który po ostatniej pora¿ce logowa³ siê ju¿
+pomy¶lnie, musisz jawnie za¿±daæ o nim informacji przy pomocy flagi \fB-u\fR.
+Mo¿esz tak¿e wy¶wietliæ wszystkich u¿ytkowników pos³uguj±c siê flag± \fB-a\fR.
+.PP
+W niektórych systemach zamiast /var/log wystêpuje /var/adm lub /usr/adm.
+.SH PLIKI
+.IR /var/log/faillog " - plik rejestracji b³êdów logowania"
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR faillog (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/gpasswd.1 b/current/man/pl/gpasswd.1
new file mode 100644
index 00000000..17f5e4ba
--- /dev/null
+++ b/current/man/pl/gpasswd.1
@@ -0,0 +1,65 @@
+.\" {PTM/WK/1999-09-16}
+.\" Copyright 1996, Rafal Maszkowski, rzm@pdi.net
+.\" All rights reserved. You can redistribute this man page and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of the
+.\" License, or (at your option) any later version.
+.\"
+.TH GPASSWD 1
+.SH NAZWA
+gpasswd \- administracja plikiem /etc/group
+.br
+.SH SK£ADNIA
+.B gpasswd \fIgrupa\fR
+.br
+.B gpasswd -a
+.I u¿ytkownik grupa
+.br
+.B gpasswd -d
+.I u¿ytkownik grupa
+.br
+.B gpasswd -R
+.I grupa
+.br
+.B gpasswd -r
+.I grupa
+.br
+.B gpasswd
+.RB [ -A
+.IR u¿ytkownik ,...]
+.RB [ -M
+.IR u¿ytkownik ,...]
+.I grupa
+.SH OPIS
+.B gpasswd
+s³u¿y do administrowania plikiem \fI/etc/group\fR (oraz \fI/etc/gshadow\fR
+je¶li zosta³a wykonana kompilacja ze zdefiniowanym SHADOWGRP). Ka¿da z grup
+mo¿e posiadaæ administratorów, cz³onków i has³o. Administrator systemu mo¿e
+pos³u¿yæ siê opcj± \fB-A\fR do zdefiniowania administratora(ów) grupy oraz
+opcj± \fB-M\fR do zdefiniowania jej cz³onków. Posiada on wszystkie prawa
+administratorów i cz³onków grup.
+.PP
+Administrator grupy mo¿e dodawaæ i usuwaæ u¿ytkowników przy pomocy,
+odpowiednio, opcji \fB-a\fR i \fB-d\fR. Administratorzy mog± te¿ u¿ywaæ opcji
+\fB-r\fR w celu usuniêcia has³a grupy. Je¿eli grupa nie posiada has³a,
+to polecenia
+.BR newgrp (1)
+do przy³±czenia siê do grupy mog± u¿ywaæ tylko jej cz³onkowie.
+Opcja \fB-R\fR wy³±cza dostêp do grupy za pomoc± polecenia
+.BR newgrp (1).
+.PP
+.B gpasswd
+wywo³ane przez administratora grupy tylko z nazw± grupy pyta o jej has³o.
+Je¿eli has³o jest ustawione, to cz³onkowie grupy mog± nadal wykonywaæ
+.BR newgrp (1)
+bez has³a, inni musz± natomiast podaæ has³o.
+.SH PLIKI
+.IR /etc/group " - informacja o grupach"
+.br
+.IR /etc/gshadow " - chroniona informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR newgrp (1),
+.BR groupadd (8),
+.BR groupdel (8),
+.BR groupmod (8),
+.BR grpck (8)
diff --git a/current/man/pl/groupadd.8 b/current/man/pl/groupadd.8
new file mode 100644
index 00000000..e80b4bd0
--- /dev/null
+++ b/current/man/pl/groupadd.8
@@ -0,0 +1,72 @@
+.\" {PTM/WK/0.1/VIII-1999}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groupadd.8,v 1.1 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPADD 8
+.SH NAZWA
+groupadd - twórz now± grupê
+.SH SK£ADNIA
+.B groupadd
+.RB [ -g
+.I gid
+.RB [ -o ]]
+.I grupa
+.SH OPIS
+Polecenie \fBgroupadd\fR tworzy nowe konto grupy pos³uguj±c siê
+warto¶ciami podanymi w wierszu poleceñ i domy¶lnymi warto¶ciami z systemu.
+W razie potrzeby zostanie wprowadzona do systemu nowa grupa.
+Polecenie \fBgroupadd\fR posiada opcje:
+.TP
+.BI -g " gid"
+Numeryczna warto¶æ identyfikatora grupy. Warto¶æ ta musi byæ niepowtarzalna,
+chyba ¿e u¿yto opcji \fB-o\fR. Warto¶æ ID grupy nie mo¿e byæ ujemna. Domy¶lnie
+u¿ywana jest najmniejsza warto¶æ identyfikatora wiêksza ni¿ 99 a wiêksza ni¿
+jakiejkolwiek innej grupy.
+Warto¶ci miêdzy 0 a 99 s± zwykle zarezerwowane dla kont systemowych.
+.SH PLIKI
+.IR /etc/group " - informacja o kontach grup"
+.br
+.IR /etc/gshadow " - bezpieczna informacja o kontach grup"
+.SH ZOBACZ TAK¯E
+.BR chfn (1),
+.BR chsh (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR passwd (1),
+.BR groupdel (8),
+.BR groupmod (8).
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Istnieje wiele programów i skryptów do zarz±dzania kontami
+u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij
+siê, ¿e korzystasz z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/groupdel.8 b/current/man/pl/groupdel.8
new file mode 100644
index 00000000..24cd254e
--- /dev/null
+++ b/current/man/pl/groupdel.8
@@ -0,0 +1,68 @@
+.\" {PTM/WK/0.1/VIII-1999}
+.\" Copyright 1991 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groupdel.8,v 1.1 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPDEL 8
+.SH NAZWA
+groupdel - usuñ grupê
+.SH SK£ADNIA
+.B groupdel
+.I grupa
+.SH OPIS
+Polecenie \fBgroupdel\fR zmienia systemowe pliki kont, usuwaj±c
+wszystkie zapisy odnosz±ce siê do \fIgrupy\fR.
+Wymieniona grupa musi istnieæ.
+.PP
+Musisz rêcznie sprawdziæ wszystkie systemy plików, by upewniæ siê, ¿e
+nie pozosta³y ¿adne pliki, dla których wymieniona grupa jest grup± w³a¶cicieli.
+.SH PRZESTROGI
+Nie mo¿esz usun±æ podstawowej grupy ¿adnego z istniej±cych u¿ytkowników.
+Musisz usun±æ u¿ytkownika przed usuniêciem takiej grupy.
+.SH PLIKI
+.IR /etc/group " - informacja o grupach"
+.br
+.IR /etc/gshadow " - bezpieczna informacja o grupach"
+.\" secure group information
+.SH ZOBACZ TAK¯E
+.BR chfn (1),
+.BR chsh (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR passwd (1),
+.BR groupadd (8),
+.BR groupmod (8).
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Istnieje wiele programów i skryptów do zarz±dzania kontami
+u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij
+siê, ¿e korzystasz z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/groupmod.8 b/current/man/pl/groupmod.8
new file mode 100644
index 00000000..bead76d1
--- /dev/null
+++ b/current/man/pl/groupmod.8
@@ -0,0 +1,77 @@
+.\" {PTM/WK/0.1/VIII-1999}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: groupmod.8,v 1.1 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH GROUPMOD 8
+.SH NAZWA
+groupmod - zmieñ dane grupy
+.SH SK£ADNIA
+.B groupmod
+.RB [ -g
+.I gid
+.RB [ -o ]]
+.RB [ -n
+.IR nazwa_grupy ]
+.I grupa
+.SH OPIS
+Polecenie \fBgroupmod\fR modyfikuje systemowe pliki kont tak, by
+odzwierciedliæ w nich zmiany grup podane w wierszu poleceñ. Obs³uguje ono
+nastêpuj±ce opcje:
+.TP
+.BI -g " gid"
+Numeryczna warto¶æ identyfikatora grupy (group ID).
+Warto¶æ ta musi byæ niepowtarzalna, chyba ¿e u¿yto opcji \fB-o\fR.
+Nie mo¿e byæ ujemna. Warto¶ci pomiêdzy 0 a 99 s± zwykle zarezerwowane
+dla grup systemowych.
+Pliki, dla których stary identyfikator jest identyfikatorem
+grupy pliku, wymagaj± rêcznej zmiany ID grupy.
+.TP
+.BI -n " nazwa_grupy"
+Nazwa grupy zostanie zmieniona z \fIgrupa\fR na \fInazwa_grupy\fR.
+.SH PLIKI
+.IR /etc/group " - informacja o grupach"
+.br
+.IR /etc/gshadow " - bezpieczna informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR chfn (1),
+.BR chsh (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR passwd (1),
+.BR groupadd (8),
+.BR groupdel (8).
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Istnieje wiele programów i skryptów do zarz±dzania kontami
+u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij
+siê, ¿e korzystasz z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/groups.1 b/current/man/pl/groups.1
new file mode 100644
index 00000000..6903d6cd
--- /dev/null
+++ b/current/man/pl/groups.1
@@ -0,0 +1,61 @@
+.\" {PRM/WK/1999-09-25}
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH GROUPS 1
+.SH NAZWA
+groups \- wy¶wietl nazwy bie¿±cych grup
+.SH SK£ADNIA
+.B groups
+.RI [ u¿ytkownik ]
+.SH OPIS
+.B groups
+wy¶wietla nazwy lub warto¶ci bie¿±cych identyfikatorów grup.
+Je¿eli warto¶æ nie posiada odpowiedniego wpisu w \fI/etc/group\fR, to zostanie
+wy¶wietlona jako numeryczny identyfikator grupy.
+Opcjonalny parametr \fIu¿ytkownik\fR powoduje wy¶wietlenie grup dla danego
+\fIu¿ytkownika\fR.
+.SH UWAGA
+Systemy nie obs³uguj±ce równoczesnych grup (tj.takie, w których u¿ytkownik mo¿e
+w danej byæ cz³onkiem tylko jednej grupy, grupy aktywnej) bêd± wy¶wietlaæ
+informacjê z \fI/etc/group\fR.
+Do zmiany bie¿±cego rzeczywistego i efektywnego identyfikatora grupy u¿ytkownik
+musi u¿yæ polecenia \fBnewgrp\fR lub \fBsg\fR.
+.SH PLIKI
+.IR /etc/group " - informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR newgrp (1),
+.BR getuid (2),
+.BR getgid (2),
+.BR getgroups (2)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/grpck.8 b/current/man/pl/grpck.8
new file mode 100644
index 00000000..55234e49
--- /dev/null
+++ b/current/man/pl/grpck.8
@@ -0,0 +1,103 @@
+.\" {PTM/WK/1999-09-17}
+.\" Copyright 1992 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH GRPCK 1
+.SH NAZWA
+grpck \- weryfikacja spójno¶ci plików grup
+.SH SK£ADNIA
+.B grpck
+.RB [ -r ]
+.RI [ group
+.IR shadow ]
+.SH OPIS
+\fBgrpck\fR weryfikuje integralno¶æ informacji autentykacji systemowej.
+Sprawdzane s± wszystkie pozycje w plikach \fI/etc/group\fR
+i \fI/etc/gshadow\fR, by upewniæ siê, ¿e ka¿da z nich posiada w³a¶ciwy format
+i poprawne dane w ka¿dym z pól. U¿ytkownik monitowany jest o usuniêcie
+pozycji, które s± sformatowane niepoprawnie lub posiadaj± inne nie daj±ce
+siê skorygowaæ b³êdy.
+.P
+Kontrolowane jest czy ka¿da pozycja posiada
+.sp
+.in +.5i
+- w³a¶ciw± liczbê pól
+.br
+- unikaln± nazwê grupy
+.br
+- poprawn± listê cz³onków i administratorów
+.in -.5i
+.sp
+.P
+Kontrola w³a¶ciwej liczby pól i niepowtarzalnej nazwy grupy jest
+decyduj±ca. Je¿eli pozycja posiada b³êdn± liczbê pól, to u¿ytkownik jest
+proszony o usuniêcie ca³ej pozycji (wiersza).
+Je¿eli u¿ytkownik nie potwierdzi decyzji o usuniêciu, to pomijane s± wszelkie
+dalsze sprawdzenia.
+Pozycja z powtórzon± nazw± grupy powoduje monit o usuniêcie, ale nadal
+bêd± wykonywane pozosta³e sprawdzenia.
+Wszystkie inne b³êdy daj± ostrze¿enia a u¿ytkownik jest zachêcany
+do uruchomienia polecenia \fBgroupmod\fR, by je poprawiæ.
+.P
+Polecenia dzia³aj±ce na pliku \fI/etc/group\fR nie potrafi± zmieniaæ
+uszkodzonych lub powielonych pozycji. W takich okoliczno¶ciach powinien byæ
+u¿ywany \fBgrpck\fR, by usun±æ nieprawid³ow± pozycjê.
+.SH OPCJE
+Domy¶lnie \fBgrpck\fR dzia³a na plikach \fI/etc/group\fR oraz \fI/etc/gshadow\fR.
+Przy pomocy parametrów \fIgroup\fR i \fIshadow\fR u¿ytkownik mo¿e wybraæ inne
+pliki.
+Dodatkowo, u¿ytkownik mo¿e wykonaæ polecenie w trybie tylko-do-odczytu, poprzez
+podanie flagi \fB-r\fR.
+Powoduje to, ¿e na wszystkie pytania dotycz±ce zmian zostanie, bez ingerencji
+u¿ytkownika, u¿yta odpowied¼ \fBnie\fR.
+.SH PLIKI
+.IR /etc/group " - informacja o kontach grup"
+.br
+.IR /etc/gshadow " - zakodowana informacja o has³ach i administratorach grup"
+.br
+.IR /etc/passwd " -informacja o u¿ytkownikach"
+.SH ZOBACZ TAK¯E
+.BR groupmod (8),
+.BR group (5),
+.BR passwd (5),
+.BR shadow (5)
+.SH DIAGNOSTYKA
+Polecenie \fBgrpck\fR koñczy pracê z nastêpuj±cymi warto¶ciami kodów:
+.IP 0 5
+Powodzenie
+.IP 1 5
+B³±d sk³adni
+.IP 2 5
+Jedna lub wiêcej z³ych pozycji pliku grup
+.IP 3 5
+Niemo¿liwe otwarcie plików grup
+.IP 4 5
+Niemo¿liwa blokada plików grup
+.IP 5 5
+Niemo¿liwa aktualizacja plików grup
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/id.1 b/current/man/pl/id.1
new file mode 100644
index 00000000..71392b94
--- /dev/null
+++ b/current/man/pl/id.1
@@ -0,0 +1,57 @@
+.\" {PTM/WK/1999-09-25}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH ID 1
+.SH NAZWA
+id - wy¶wietl nazwy bie¿±cych ID u¿ytkownika i grupy
+.SH SK£ADNIA
+.B id
+.RB [ -a ]
+.SH OPIS
+.B id
+wy¶wietla bie¿±ce nazwy (lub warto¶ci) rzeczywistych i efektywnych
+identyfikatorów u¿ytkownika i grupy.
+Je¿eli dana warto¶æ nie posiada odpowiedniego wpisu w \fI/etc/passwd\fR
+lub \fI/etc/group\fR, to zostanie wy¶wietlona bez odpowiedniej nazwy.
+Opcjonalna flaga \fB-a\fR wy¶wietla zestaw grup w systemach, które obs³uguj±
+równoczesne cz³onkostwo w wielu grupach.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/group " - informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR getuid (2),
+.BR getgid (2),
+.BR getgroups (2)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/lastlog.8 b/current/man/pl/lastlog.8
new file mode 100644
index 00000000..63d5e270
--- /dev/null
+++ b/current/man/pl/lastlog.8
@@ -0,0 +1,64 @@
+.\" {PTM/WK/1999-09-18}
+.\" Copyright 1992, Phillip Street and Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)lastlog.8 3.3 08:24:58 29 Sep 1993 (National Guard Release)
+.\"
+.TH LASTLOG 8
+.SH NAZWA
+lastlog \- sprawd¼ plik ostatnich logowañ (lastlog)
+.SH SK£ADNIA
+.B lastlog
+.RB [ -u
+.IR uid ]
+.RB [ -t
+.IR dni
+.SH OPIS
+\fBlastlog\fR formatuje i wy¶wietla zawarto¶æ dziennika ostatnich logowañ,
+\fI/var/log/lastlog\fR. Wy¶wietlone zostan± \fBnazwa u¿ytkownika\fR,
+\fBport\fR i \fBczas ostatniego logowania\fR.
+Domy¶lnie (bez flag) pozycje pliku wy¶wietlane s± w kolejno¶ci identyfikatorów
+u¿ytkowników (UID).
+Wprowadzenie opcji \fB-u \fInazwa_u¿ytkownika\fR spowoduje wy¶wietlenie
+pozycji opisuj±cej ostatnie rozpoczêcie sesji tylko dla tego u¿ytkownika.
+U¿ycie \fB-t \fIdni\fR powoduje, ¿e bêd± wy¶wietlone ostatnie logowania
+u¿ytkowników nowsze ni¿ sprzed zadanej liczby \fIdni\fR.
+Opcja \fB-t\fR przes³ania u¿ycie opcji \fB-u\fR.
+.PP
+Je¿eli u¿ytkownik nigdy siê nie logowa³ to zamiast portu i czasu logowania
+zostanie wy¶wietlony komunikat \fB"**Never logged in**"\fR (nigdy siê nie
+logowa³).
+.SH PLIKI
+.IR /var/log/lastlog " - dziennik ostatnich logowañ"
+.SH PRZESTROGI
+Du¿e luki w numeracji UID powoduj±, ¿e program bêdzie pracowa³ d³u¿ej, nie
+wy¶wietlaj±c wyników (np. je¶li mmdf=800, za¶ ostatni uid=170, to program
+bêdzie sprawia³ wra¿enie zawieszonego w trakcie przetwarzania uid 171-799).
+.SH AUTORZY
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.br
+Phillip Street
diff --git a/current/man/pl/limits.5 b/current/man/pl/limits.5
new file mode 100644
index 00000000..9ffa0f59
--- /dev/null
+++ b/current/man/pl/limits.5
@@ -0,0 +1,79 @@
+.\" {PTM/WK/1999-09-18}
+.TH LIMITS 5
+.SH NAZWA
+limits \- definicja ograniczeñ zasobów
+.SH OPIS
+Plik
+.I limits
+(domy¶lnie /etc/limits lub LIMITS_FILE zdefiniowane w config.h)
+opisuje ograniczenia zasobów, jakie chcia³by¶ narzuciæ u¿ytkownikom.
+W³a¶cicielem tego pliku powinien byæ u¿ytkownik root i wy³±cznie dla niego
+plik ten powinien byæ dostêpny do odczytu.
+.PP
+Domy¶lnie u¿ytkownikowi 'root' nie s± narzucane ¿adne ograniczenia.
+W rzeczywisto¶ci, przy u¿yciu tego sposobu nie jest mo¿liwe narzucenie limitów
+dla kont równowa¿nych root (kont z UID równym 0).
+.PP
+Ka¿dy wiersz definiuje ograniczenie dla u¿ytkownika w postaci:
+.sp
+.I u¿ytkownik £AÑCUCH_OGRANICZEÑ
+.PP
+\fB£AÑCUCH OGRANICZEÑ\fP sk³ada siê z po³±czonych definicji ograniczeñ zasobów.
+Ka¿de ograniczenie opisywane jest liter± z nastêpuj±c± po niej warto¶ci±
+numeryczn± limitu.
+.PP
+Dozwolone s± nastêpuj±ce identyfikatory:
+.sp
+A: max. przestrzeñ adresowa (KB)
+.br
+C: max. rozmiar pliku core (KB)
+.br
+D: max. rozmiar danych (KB)
+.br
+F: maksymalny rozmiar pliku (KB)
+.br
+M: max. locked-in-memory address space (KB)
+.br
+N: max. liczba otwartych plików
+.br
+R: max. resident set size (KB)
+.br
+S: max. rozmiar stosu (KB)
+.br
+T: max. czas procesora (CPU) (MIN)
+.br
+U: max. liczba procesów
+.br
+L: max. liczba sesji pracy dla tego u¿ytkownika
+.br
+P: priorytet procesu, ustawiany przez \fBsetpriority\fR(2).
+.PP
+Na przyk³ad, \fIL2D2048N5\fP jest poprawnym \fB£AÑCUCHEM OGRANICZEÑ\fP.
+Z uwagi na lepsz± czytelno¶ci przyjêto, ¿e poni¿sze zapisy s± równowa¿ne:
+.sp
+nazwa_u¿ytkownika L2D2048N5
+.br
+nazwa_u¿ytkownika L2 D2048 N5
+.PP
+Nale¿y podkre¶liæ, ¿e reszta wiersza po \fInazwie_u¿ytkownika\fP traktowana
+jest jako ³añcuch ograniczeñ, zatem komentarze nie s± dozwolone. Nieprawid³owy
+³añcuch ograniczeñ zostanie odrzucony (nie bêdzie brany pod uwagê) przez
+program login.
+.PP
+Nazwa u¿ytkownika równa "\fB*\fP" oznacza wpis domy¶lny.
+Je¿eli w pliku \fBLIMITS_FILE\fP posiadasz wiele takich wpisów, to jako
+domy¶lny zostanie u¿yty ostatni z nich.
+.PP
+Pojedyncza kreska "\fB-\fP" ca³kowicie wy³±cza ograniczenia dla u¿ytkownika.
+.PP
+Zauwa¿ te¿, proszê, ¿e wszystkie te ograniczenia definiowane s± w odniesieniu
+do pojedynczej sesji (per login). Nie s± one globalne ani sta³e. Byæ mo¿e bêd±
+kiedy¶ ograniczenia globalne, ale na razie tyle musi wystarczyæ ;)
+.SH PLIKI
+.I /etc/limits
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR setpriority (2),
+.BR setrlimit (2)
+.SH AUTOR
+Cristian Gafton (gafton@sorosis.ro)
diff --git a/current/man/pl/login.1 b/current/man/pl/login.1
new file mode 100644
index 00000000..ecedc24c
--- /dev/null
+++ b/current/man/pl/login.1
@@ -0,0 +1,134 @@
+.\" {PTM/WK/1999-09-25}
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH LOGIN 1
+.SH NAZWA
+login \- rozpocznij sesjê pracy w systemie
+.SH SK£ADNIA
+.B login
+.RI [ u¿ytkownik " [" zmienne_¶rodowiska ]]
+.\" XXX - udokumentowaæ opcje -f -h -p -r
+.SH OPIS
+.B login
+s³u¿y do utworzenia nowej sesji pracy z systemem. Zwykle wywo³ywane jest
+automatycznie w odpowiedzi na zachêtê
+.I login:
+na terminalu u¿ytkownika.
+.B login
+mo¿e byæ specyficzne dla pow³oki i mo¿e zostaæ wywo³ane jako podproces.
+Najczê¶ciej,
+.B login
+traktowane jest przez pow³okê jako \fBexec login\fR, co powoduje opuszczenie
+przez u¿ytkownika bie¿±cej pow³oki.
+Próba wykonania \fBlogin\fR z pow³oki innej ni¿ zg³oszeniowa powoduje komunikat
+o b³êdzie.
+.PP
+Przy wywo³aniu polecenia z zachêty \fIlogin:\fR, u¿ytkownik mo¿e po swojej
+nazwie wprowadziæ zmienne ¶rodowiska. Zmienne te wprowadzane s± w postaci:
+\fBNAZWA=WARTO¦Æ\fR. Nie wszystkie zmienne mog± jednak byæ ustawione w ten
+sposób, szczególnie \fBPATH\fR, \fBHOME\fR i \fBSHELL\fR.
+Dodatkowo, zakazane mo¿e byæ \fBIFS\fR (input field separator: separator pól
+wej¶ciowych), je¿eli pow³ok± zg³oszeniow± u¿ytkownika \fB/bin/sh\fR.
+.PP
+U¿ytkownik pytany jest o has³o, je¶li takowe istnieje.
+Dla zapobie¿enia ujawnieniu has³a wy¶wietlanie wprowadzanych znaków jest
+wy³±czone. Dozwolona jest jedynie niewielka liczba nieudanych prób podania
+has³a. Po wyczerpaniu limitu prób \fBlogin\fR koñczy pracê za¶ po³±czenie
+komunikacyjne jest zrywane.
+.PP
+Je¿eli dla twego konta w³±czona jest kontrola wa¿no¶ci has³a, mo¿esz byæ
+proszony o podanie nowego has³a przed kontynuacj±. Bêdziesz wówczas musia³
+podaæ stare i nowe has³o. Wiêcej informacji na ten temat znajdziesz
+w \fBpasswd \fR(1).
+.PP
+Po poprawnym rozpoczêciu sesji (zalogowaniu siê), zostanie wy¶wietlona
+wiadomo¶æ dnia (je¶li jest) i informacja o stanie skrzynki pocztowej.
+Mo¿esz wy³±czyæ wy¶wietlanie zawarto¶ci pliku wiadomo¶ci dnia,
+\fI/etc/motd\fR, tworz±c zerowej wielko¶ci plik \fI.hushlogin\fR
+w swoim katalogu domowym.
+Informacja o stanie skrzynki pocztowej jest jedn± z:
+"\fBYou have new mail.\fR" (masz now± pocztê),
+"\fBYou have mail.\fR" (masz pocztê), lub "\fBNo Mail.\fR" (brak poczty) -
+stosownie do stanu skrzynki.
+.PP
+Identyfikator u¿ytkownika i grupy (UID i GID) zostan± ustawione wed³ug warto¶ci
+w pliku \fI/etc/passwd\fR.
+Warto¶ci \fB$HOME\fR, \fB$SHELL\fR, \fB$PATH\fR, \fB$LOGNAME\fR
+i \fB$MAIL\fR ustawiane s± stosownie do odpowiednich pól danego wpisu pliku
+hase³.
+Mog± byæ ustalane równie¿ warto¶ci ulimit, umask oraz nice wed³ug wpisów w polu
+GECOS.
+.PP
+W niektórych systemach zostanie ustawiona zmienna ¶rodowiskowa \fB$TERM\fR,
+wskazuj±ca na typ terminala na linii tty, jak podano w \fI/etc/ttytype\fR.
+.PP
+Mo¿e tak¿e zostaæ wykonany skrypt startowy (inicjacyjny) twojego interpretatora
+poleceñ.
+Przegl±dnij, proszê, odpowiedni± sekcjê dokumentacji opisuj±c± bardziej
+szczegó³owo tê funkcjê.
+.SH PRZESTROGI
+Niniejsza wersja \fBlogin\fR posiada wiele opcji kompilacji, z których tylko
+czê¶æ bêdzie mieæ zastosowanie w danej instalacji.
+.PP
+Po³o¿enie plików mo¿e byæ ró¿ne w zale¿no¶ci od konfiguracji systemu.
+.SH PLIKI
+.IR /etc/utmp " - lista bie¿±cych sesji pracy"
+.br
+.IR /etc/wtmp " - lista poprzednich sesji pracy"
+.br
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - zakodowane has³a i informacja o ich wa¿no¶ci"
+.br
+.IR /etc/motd " - plik 'wiadomo¶ci dnia'"
+.br
+.IR /etc/nologin " - zapobiega logowaniu innych ni¿ root"
+.br
+.IR /etc/ttytype " - lista typów terminali"
+.br
+.IR $HOME/.profile " - skrypt startowy domy¶lnej pow³oki"
+.br
+.IR $HOME/.hushlogin " - zapobiega m.in. wy¶wietlaniu wiadomo¶ci dnia"
+.br
+.SH ZOBACZ TAK¯E
+.BR getty (8),
+.BR mail (1),
+.BR passwd (1),
+.BR sh (1),
+.BR su (1),
+.BR login.defs (5),
+.\" .BR d_passwd (5),
+.BR passwd (5),
+.BR nologin (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/login.access.5 b/current/man/pl/login.access.5
new file mode 100644
index 00000000..cfcad56c
--- /dev/null
+++ b/current/man/pl/login.access.5
@@ -0,0 +1,54 @@
+.\" {PTM/WK/1999-09-17}
+.TH LOGIN.ACCESS 5
+.\" .Dt SKEY.ACCESS 5
+.\" .Os FreeBSD 1.2
+.SH NAZWA
+login.access \- tabela kontroli dostêpu logowania
+.SH OPIS
+Plik
+.I login.access
+okre¶la kombinacje (u¿ytkownik, host) i/lub (u¿ytkownik, tty)
+dla których logowanie bêdzie albo przyjête albo odrzucone.
+.PP
+Gdy kto¶ siê loguje, plik
+.I login.access
+przeszukiwany jest do znalezienia pierwszej pozycji pasuj±cej do danej
+kombinacji (u¿ytkownik, host), lub, w przypadku logowañ nie-sieciowych
+kombinacji (u¿ytkownik, tty). Pole zezwolenia w tej tablicy pozycji okre¶la
+czy logowanie bêdzie przyjête czy odrzucone.
+.PP
+Ka¿dy wiersz tabeli kontroli dostêpu logowania posiada trzy, oddzielone
+znakiem dwukropka, pola:
+.sp 1
+.IR zezwolenie : u¿ytkownicy : pochodzenie
+.sp 1
+Pierwsze pole powinno zawieraæ znak "\fB+\fR" (dostêp zapewniony) lub "\fB-\fR"
+(zakaz dostêpu). Drugie z pól powinno zawieraæ listê jednego lub wiêcej nazw
+u¿ytkowników, grup lub s³owo
+.B ALL
+(zawsze pasuje do wszystkich). Trzecie pole powinno byæ list± jednej lub wiêcej
+nazw tty (dla logowañ nie-sieciowych), nazw hostów, domen (rozpoczynaj±cych siê
+od kropki), adresów hostów, internetowych numerów sieci (koñcz±cych siê
+kropk±), s³owem
+.B ALL
+(wszystkie - zawsze pasuje) lub
+.B LOCAL
+(dopasowuje dowolny ³añcuch nie zawieraj±cy kropki).
+Je¿eli uruchomisz NIS mo¿esz u¿yæ @nazwagrupysieciowej we wzorcu hosta
+lub u¿ytkownika.
+.\" @netgroupname
+.PP
+Operator
+.B EXCEPT
+(oprócz) umo¿liwia pisanie z³o¿onych regu³.
+.PP
+Plik grup przeszukiwany jest wy³±cznie wtedy, gdy nazwa nie pasuje do
+loguj±cego siê u¿ytkownika. Dopasowywane s± tylko te grupy, w których
+u¿ytkownik jest jawnie wymieniony: program nie sprawdza warto¶ci
+identyfikatora grupy g³ównej u¿ytkownika.
+.SH PLIKI
+.I /etc/login.access
+.SH ZOBACZ TAK¯E
+.BR login (1)
+.SH AUTOR
+Guido van Rooij
diff --git a/current/man/pl/login.defs.5 b/current/man/pl/login.defs.5
new file mode 100644
index 00000000..79c907de
--- /dev/null
+++ b/current/man/pl/login.defs.5
@@ -0,0 +1,557 @@
+.\" {PTM/WK/1999-09-18}
+.\" Copyright 1991 - 1993, Julianne Frances Haugh and Chip Rosenthal
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH LOGIN 5
+.SH NAZWA
+/etc/login.defs \- konfiguracja logowania
+.SH OPIS
+Plik
+.I /etc/login.defs
+definiuje specyficzn± dla naszej maszyny konfiguracjê pakietu shadow login.
+Plik ten jest wymagany. Jego nieobecno¶æ nie wstrzyma dzia³ania systemu,
+ale prawdopodobnie spowoduje nieprzewidywalne dzia³anie.
+.PP
+Plik ten jest czytelnym plikiem tekstowym. Ka¿dy z jego wierszy opisuje jeden
+parametr konfiguracji. Wiersze sk³adaj± siê z nazwy parametru i jego warto¶ci,
+oddzielonych bia³ym znakiem. Ignorowane s± puste wiersze i wiersze komentarzy.
+Komentarze rozpoczynaj± siê od znaku '#', który musi byæ pierwszym znakiem
+wiersza (pomijaj±c bia³e znaki).
+.PP
+Istniej± cztery typy warto¶ci parametrów: napisy, logiczne (boolean),
+liczby i d³ugie liczby (long numbers). Napis jest z³o¿ony
+z dowolnych znaków drukowalnych. Parametr logiczny mo¿e mieæ albo warto¶æ
+"yes" albo "no". Niezdefiniowanemu parametrowi logicznemu lub parametrowi,
+któremu przypisano warto¶æ inn± od powy¿szych przypisane zostanie "no".
+Liczby (zarówno zwyk³e jak i d³ugie) mog± byæ warto¶ciami dziesiêtnymi,
+ósemkowymi (poprzed¼ warto¶æ cyfr± "0") albo szesnastkowymi (poprzed¼ warto¶æ
+sekwencj± "0x"). Maksymalne warto¶ci zwyk³ych i d³ugich parametrów
+numerycznych zale¿± od maszyny.
+.PP
+Obs³ugiwane s± nastêpuj±ce opcje konfiguracyjne:
+.\"
+.IP "CHFN_AUTH (logiczna)"
+Je¿eli ma warto¶æ
+.IR yes ,
+to programy
+.B chfn
+i
+.B chsh
+bêd± pytaæ o has³o przed dokonaniem zmian, chyba ¿e uruchamiane s± przez
+superu¿ytkownika.
+.\"
+.IP "CHFN_RESTRICT (napis)"
+Ten parametr okre¶la, jakie warto¶ci w polu
+.I gecos
+pliku
+.I passwd
+mog± byæ zmieniane przez zwyk³ych u¿ytkowników za pomoc± programu
+.B chfn
+Mo¿e on byæ dowoln± kombinacj± liter
+.IR f ,
+.IR r ,
+.IR w ,
+.IR h ,
+oznaczaj±cych odpowiednio: Full name (pe³na nazwa), Room number (numer pokoju),
+Work phone (telefon s³u¿bowy) i Home phone (telefon domowy).
+Je¶li parametr nie jest podany, to zmian mo¿e dokonywaæ wy³±cznie
+superu¿ytkownik.
+.\"
+.IP "CONSOLE (napis)"
+Je¶li podana, definicja ta okre¶la ograniczony zestaw linii, na których
+dozwolone jest rozpoczynanie sesji u¿ytkownika root. Próby logowania
+u¿ytkownika root niespe³niaj±ce ustalonych tu kryteriów zostan± odrzucone.
+Warto¶æ tego pola mo¿e wyst±piæ w jednej z dwu postaci: albo pe³nej nazwy
+¶cie¿kowej pliku, jak na przyk³ad
+.sp
+.ft I
+ CONSOLE /etc/consoles
+.ft R
+.sp
+albo listy linii terminalowych rozdzielonych dwukropkami, jak poni¿ej:
+.sp
+.ft I
+ CONSOLE console:tty01:tty02:tty03:tty04
+.ft R
+.sp
+(Zauwa¿, ¿e wymienione tu nazwy nie zawieraj± ¶cie¿ki /dev/).
+Je¿eli podano ¶cie¿kow± nazwê pliku, to ka¿dy jego wiersz powinien okre¶laæ
+jedn± liniê terminalow±. Je¶li parametr ten nie jest zdefiniowany albo podany
+plik nie istnieje, to u¿ytkownik root bêdzie móg³ siê logowaæ z dowolnej linii
+terminalowej. Poniewa¿ usuniêcie lub obciêcie pliku definiuj±cego
+dozwolone linie mo¿e spowodowaæ nieautoryzowane logowania roota, plik ten musi
+byæ chroniony. Tam, gdzie bezpieczeñstwo jest spraw± kluczow±, powinna byæ
+u¿ywana postaæ listy separowanej dwukropkami, co chroni przed potencjaln±
+prób± ataku w opisany sposób.
+.\"
+.IP "CONSOLE_GROUPS (napis)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "CRACKLIB_DICTPATH (napis)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "DEFAULT_HOME (logiczna)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "DIALUPS_CHECK_ENAB (logiczna)"
+Je¿eli ma warto¶æ
+.I yes
+a plik
+.I /etc/dialups
+istnieje, to na liniach telefonicznych wyszczególnionych w tym pliku s±
+w³±czane wtórne has³a (has³a telefoniczne). Plik ten powinien zawieraæ listê
+linii telefonicznych (dialups), po jednej w wierszu, na przyk³ad:
+.nf
+.sp
+.ft I
+ ttyfm01
+ ttyfm02
+ \0\0.
+ \0\0.
+ \0\0.
+.ft R
+.sp
+.fi
+.\"
+.IP "ENVIRON_FILE (napis)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "ENV_HZ (napis)"
+Parametr ten okre¶la warto¶æ parametru ¶rodowiska HZ. Przyk³ad u¿ycia:
+.sp
+ \fIENV_HZ HZ=50\fR
+.sp
+Je¿eli jest on zdefiniowany, to nie zostanie ustanowiona ¿adna warto¶æ HZ.
+.\"
+.IP "ENV_PATH (napis)"
+Parametr ten musi byæ zdefiniowany jako ¶cie¿ka przeszukiwania dla zwyk³ych
+u¿ytkowników. Przy logowaniu z UID innym ni¿ zero, zmienna ¶rodowiskowa PATH
+jest inicjowana t± w³a¶nie warto¶ci±. Jest to parametr wymagany; je¿eli nie
+zostanie zdefiniowany, to zostanie nadana, byæ mo¿e niepoprawna, warto¶æ
+domy¶lna.
+.\"
+.IP "ENV_SUPATH (napis)"
+Parametr ten musi byæ zdefiniowany jako ¶cie¿ka przeszukiwania dla
+superu¿ytkownika. Przy rozpoczynaniu sesji z UID równym zero, zmienna
+¶rodowiskowa PATH jest inicjowana t± w³a¶nie warto¶ci±. Jest to parametr
+wymagany; je¿eli nie zostanie zdefiniowany, to zostanie nadana, byæ mo¿e
+niepoprawna, warto¶æ domy¶lna.
+.\"
+.IP "ENV_TZ (napis)"
+Parametr ten zawiera informacjê s³u¿±c± do utworzenia zmiennej ¶rodowiskowej TZ.
+Jego warto¶æ musi byæ albo wprost wymagan± zawarto¶ci± TZ, albo
+pe³n± nazw± ¶cie¿kow± pliku zawieraj±cego tê informacjê. Przyk³ad u¿ycia:
+.sp
+ \fIENV_TZ\0\0\0\0TZ=CST6CDT\fP
+.sp
+lub
+.sp
+ \fIENV_TZ\0\0\0\0/etc/tzname\fP
+.sp
+Je¿eli podano nieistniej±cy plik, to TZ zostanie zainicjowane pewn± warto¶ci±
+domy¶ln±. Je¿eli nie zdefiniowano tego parametru to nie bêdzie ustawiona
+¿adna warto¶æ TZ.
+.\"
+.IP "ERASECHAR (liczba)"
+T± warto¶ci± jest inicjowany terminalowy znak
+.I erase
+(kasowania). Jest to obs³ugiwane tylko w systemach z interfejsem
+.IR termio,
+np. System V. Je¿eli nie podano parametru, to znak kasowania zostanie
+zainicjowany na backspace. Informacjê powi±zan± znajdziesz w opisie KILLCHAR.
+.\"
+.IP "FAILLOG_ENAB (logiczna)"
+Je¿eli ustawiona na
+.I yes
+to nieudane logowania bêd± odnotowywane w pliku
+.I /var/log/faillog
+w formacie
+.BR faillog (8).
+.\"
+.IP "FAIL_DELAY (liczba)"
+Czas opó¼nienia, wyra¿ony w sekundach, po ka¿dej nieudanej próbie logowania.
+.\"
+.IP "FAKE_SHELL (napis)"
+Zamiast rzeczywistej pow³oki u¿ytkownika zostanie uruchomiony program okre¶lony
+warto¶ci± tego parametru. Nazwa widoczna (argv[0]) programu bêdzie jednak
+nazw± pow³oki. Program przed uruchomieniem faktycznej pow³oki mo¿e wykonywaæ
+dowoln± akcjê (logowanie, dodatkowe uwierzytelnianie, banner itp.).
+.\"
+.IP "FTMP_FILE (napis)"
+Okre¶la pe³n± ¶cie¿kow± nazwê pliku, w którym rejestrowane s± nieudane próby
+rozpoczynania sesji pracy. W przypadku nieudanej próby logowania do pliku
+dopisywana jest pozycja o formacie
+.IR utmp .
+Zauwa¿, ¿e ró¿ni siê to od rejestracji niepomy¶lnych logowañ do
+.IR /var/log/faillog ,
+gdy¿ opisywana funkcja odnotowuje wszystkie nieudane próby, podczas gdy
+"faillog" kumuluje informacjê o pora¿kach danego u¿ytkownika. Je¶li nie
+podano tego parametru, to rejestracja bêdzie wy³±czona. Powi±zane informacje
+znajdziesz w opisie FAILLOG_ENAB i LOG_UNKFAIL_ENAB.
+.\"
+.IP "GID_MAX (liczba)"
+.IP "GID_MIN (liczba)"
+Zakres identyfikatorów grup, w obrêbie którego mo¿e wybieraæ program
+.BR groupadd .
+.\"
+.IP "HUSHLOGIN_FILE (nazwa)"
+Parametr u¿ywany do ustalenia okoliczno¶ci cichego logowania ("hushlogin").
+Okoliczno¶ci te mog± byæ ustalone na dwa sposoby. Po pierwsze, je¿eli warto¶ci±
+parametru jest nazwa pliku, a plik ten istnieje w katalogu domowym u¿ytkownika,
+to wprowadzane s± warunki cichego logowania. Zawarto¶æ pliku jest ignorowana;
+sama jego obecno¶æ powoduje ciche logowanie. Po drugie, je¿eli warto¶ci±
+parametru jest pe³na nazwa ¶cie¿kowa pliku a w pliku tym znaleziona zostanie
+nazwa u¿ytkownika lub nazwa jego pow³oki, to wprowadzone zostan± warunki
+cichego logowania. W tym przypadku, plik powinien mieæ format podobny do:
+.nf
+.sp
+.ft I
+ demo
+ /usr/lib/uucp/uucico
+ \0\0.
+ \0\0.
+ \0\0.
+.ft R
+.sp
+.fi
+Je¿eli nie zdefiniowano tego parametru, to warunki cichego logowania nigdy
+nie wyst±pi±. W trakcie cichego logowanie wstrzymane jest wy¶wietlanie
+wiadomo¶ci dnia (message of the day), ostatniego udanego i nieudanego
+rozpoczêcia sesji pracy, wy¶wietlanie stanu skrzynki pocztowej i sprawdzenie
+wieku has³a. Zauwa¿, ¿e zezwolenie na pliki cichego logowania w katalogach
+domowych u¿ytkowników pozwala im na wstrzymanie kontroli wa¿no¶ci
+has³a. Informacje zwi±zane z tym tematem znajdziesz w opisach MOTD_FILE,
+FILELOG_ENAB, LASTLOG_ENAB i MAIL_CHECK_ENAB.
+.\"
+.IP "ISSUE_FILE (napis)"
+Pe³na ¶cie¿kowa nazwa pliku wy¶wietlanego przed ka¿d± zachêt± do logowania.
+.\"
+.IP "KILLCHAR (liczba)"
+T± warto¶ci± inicjowany jest terminalowy znak
+.IR kill .
+Jest to obs³ugiwane tylko w systemach z interfejsem
+.IR termio,
+np. System V. Je¿eli nie podano parametru, to znak kasowania zostanie
+zainicjowany na \s-2CTRL/U\s0. Informacjê powi±zan± znajdziesz w opisie
+ERASECHAR.
+.\"
+.IP "LASTLOG_ENAB (logiczna)"
+Je¶li ma warto¶æ
+.IR yes ,
+i istnieje plik
+.IR /var/log/lastlog ,
+to w tym pliku bêdzie rejestrowane poprawne rozpoczêcie sesji pracy u¿ytkownika
+(zalogowanie siê). Ponadto, je¶li opcja ta jest w³±czona, to podczas logowania
+siê u¿ytkownika bêdzie wy¶wietlana informacja o liczbie ostatnich udanych
+i nieudanych logowañ. Zakoñczone niepowodzeniem logowania nie bêd± wy¶wietlane
+je¶li nie w³±czono FAILLOG_ENAB. W warunkach cichego logowanie nie
+bêd± wy¶wietlane informacje ani o pomy¶lnych ani o niepomy¶lnych logowaniach.
+.\"
+.IP "LOGIN_RETRIES (liczba)"
+Dozwolona liczba prób logowania przed zakoñczeniem pracy programu
+.BR login .
+.\"
+.IP "LOGIN_STRING (napis)"
+XXX powinno zostaæ udokumentowane.
+.IP "LOGIN_TIMEOUT (liczba)"
+XXX powinno zostaæ udokumentowane.
+.IP "LOG_OK_LOGINS (logiczna)"
+XXX powinno zostaæ udokumentowane.
+.IP "LOG_UNKFAIL_ENAB (logiczna)"
+Je¶li posiada warto¶æ
+.I yes
+to nieznane nazwy u¿ytkowników bêd± równie¿ odnotowywane je¶li w³±czone jest
+rejestrowanie nieudanych prób rozpoczêcia sesji. Zauwa¿, ¿e niesie to ze sob±
+potencjalne zagro¿enie bezpieczeñstwa: powszechn± przyczyn± nieudanego
+logowania jest zamiana nazwy u¿ytkownika i has³a, tryb ten zatem spowoduje,
+¿e czêsto w rejestrach nieudanych logowañ bêd± siê odk³adaæ jawne has³a.
+Je¿eli opcja ta jest wy³±czona, to nieznane nazwy u¿ytkowników bêd± pomijane
+w komunikatach o nieudanych próbach logowania.
+.\"
+.IP "MAIL_CHECK_ENAB (logiczna)"
+Je¿eli ma warto¶æ
+.IR yes ,
+to u¿ytkownik po rozpoczêciu sesji pracy bêdzie powiadamiany o stanie swojej
+skrzynki pocztowej. Informacjê zwi±zan± z tym tematem znajdziesz w opisie
+MAIL_DIR.
+.\"
+.IP "MAIL_DIR (napis)"
+Okre¶la pe³n± nazwê ¶cie¿kow± do katalogu zawieraj±cego pliki skrzynki
+pocztowej u¿ytkownika. Do powy¿szej ¶cie¿ki doklejana jest nazwa u¿ytkownika,
+tworz±c w ten sposób zmienn± ¶rodowiskow± MAIL - ¶cie¿kê do skrzynki
+u¿ytkownika. Musi byæ zdefiniowany albo niniejszy parametr albo parametr
+MAIL_FILE; je¶li nie zostan± zdefiniowane, to zostanie nadana, byæ mo¿e
+niepoprawna, warto¶æ domy¶lna. Zobacz tak¿e opis MAIL_CHECK_ENAB.
+.\"
+.IP "MAIL_FILE (napis)"
+Okre¶la nazwê pliku skrzynki pocztowej u¿ytkownika. Nazwa ta doklejana jest
+na koniec nazwy katalogu domowego u¿ytkownika tworz±c zmienn± ¶rodowiskow±
+MAIL - ¶cie¿kê do skrzynki u¿ytkownika. Musi byæ zdefiniowany albo niniejszy
+parametr albo parametr MAIL_DIR; je¶li nie zostan± zdefiniowane, to zostanie
+nadana, byæ mo¿e niepoprawna, warto¶æ domy¶lna. Zobacz tak¿e opis
+MAIL_CHECK_ENAB.
+.\"
+.IP "MD5_CRYPT_ENAB (logiczna)"
+Je¿eli ma warto¶æ
+.IR yes ,
+to program
+.B passwd
+bêdzie kodowaæ nowo zmieniane has³a przy pomocy nowego algorytmu
+.BR crypt (3),
+opartego o MD-5. Algorytm ten pierwotnie pojawi³ siê we FreeBSD i jest te¿
+obs³ugiwany przez libc-5.4.38 oraz glibc-2.0 (lub wy¿sz±) w Linuksie.
+Pozwala on na u¿ywanie hase³ d³u¿szych ni¿ 8 znaków (ograniczone przez
+.BR getpass (3)
+do 127 znaków), ale nie jest zgodny z tradycyjnymi implementacjami polecenia
+.BR crypt (3).
+.\"
+.IP "MOTD_FILE (napis)"
+Okre¶la listê rozdzielonych dwukropkami ¶cie¿ek do plików "wiadomo¶ci dnia"
+(message of the day, MOTD). Je¶li podany plik istnieje, to jego zawarto¶æ jest
+wy¶wietlana u¿ytkownikowi podczas rozpoczynania przez niego sesji pracy.
+Je¿eli parametr ten jest niezdefiniowany lub wykonywane jest ciche logowanie,
+to informacja ta bêdzie pomijana.
+.\"
+.IP "NOLOGINS_FILE (napis)"
+Okre¶la pe³n± nazwê ¶cie¿kow± pliku zabraniaj±cego logowañ dla u¿ytkowników
+innych ni¿ root. Je¿eli plik ten istnieje a u¿ytkownik inny ni¿ root usi³uje
+siê zalogowaæ, to wy¶wietlana zostanie zawarto¶æ pliku a u¿ytkownik bêdzie
+roz³±czony. Je¿eli nie podano tego parametru, to opisana funkcja bêdzie
+wy³±czona.
+.\"
+.IP "NOLOGIN_STR (napis)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "OBSCURE_CHECKS_ENAB (logiczna)"
+Je¿eli ma warto¶æ
+.IR yes ,
+to program
+.B passwd
+przed akceptacj± zmiany has³a bêdzie wykonywa³ dodatkowe sprawdzenia.
+Kontrole te s± do¶æ proste, a ich u¿ycie jest zalecane.
+Te sprawdzenia nieoczywisto¶ci s± pomijane, je¿eli
+.B passwd
+uruchamiane jest przez u¿ytkownika
+.IR root .
+Zobacz tak¿e opis PASS_MIN_LEN.
+.\"
+.IP "PASS_ALWAYS_WARN (logiczna)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "PASS_CHANGE_TRIES (liczba)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "PASS_MIN_DAYS (liczba)"
+Minimalna liczba dni miêdzy dozwolonymi zmianami has³a. Jakiekolwiek próby
+zmiany has³a podejmowane wcze¶niej zostan± odrzucone. Je¿eli nie podano tego
+parametru, to przyjêta zostanie warto¶æ zerowa.
+.\"
+.IP "PASS_MIN_LEN (liczba)"
+Minimalna liczba znaków w akceptowalnym ha¶le. Próba przypisania has³a o
+mniejszej liczbie znaków zostanie odrzucona. Warto¶æ zero wy³±cza tê
+kontrolê. Je¶li nie podano parametru, to przyjêta zostanie warto¶æ zerowa.
+.\"
+.IP "PASS_MAX_DAYS (liczba)"
+Maksymalna liczba dni, przez jak± mo¿e byæ u¿ywane has³o. Je¶li has³o jest
+stanie siê starsze, to rachunek zostanie zablokowany. Je¶li nie podano, to
+zostanie przyjêta bardzo du¿a warto¶æ.
+.\"
+.IP "PASS_MAX_LEN (liczba)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "PASS_WARN_AGE (liczba)"
+Liczba dni ostrzegania przed wyga¶niêciem has³a. Warto¶æ zerowa oznacza,
+¿e ostrze¿enie wyst±pi wy³±cznie w dniu utraty wa¿no¶ci has³a. Warto¶æ
+ujemna oznacza brak ostrze¿eñ. Brak parametru oznacza, ¿e ostrze¿enia nie
+bêd± wy¶wietlane.
+.\"
+.IP "PORTTIME_CHECKS_ENAB (logiczna)"
+Je¶li ma warto¶æ
+.IR yes ,
+za¶ plik
+.I /etc/porttime
+istnieje, to bêdzie on przegl±dany, by upewniæ siê czy u¿ytkownik mo¿e siê
+w danej chwili zalogowaæ na danej linii. Patrz tak¿e podrêcznik
+.BR porttime (5)
+.\"
+.IP "QMAIL_DIR (napis)"
+Dla u¿ytkowników Qmail, parametr ten okre¶la katalog, w którym przechowywana
+jest hierarchia Maildir.
+Zobacz te¿ MAIL_CHECK_ENAB.
+.\"
+.IP "QUOTAS_ENAB (logiczna)"
+Je¶li ma warto¶æ
+.I yes ,
+wówczas dla danego u¿ytkownika "ulimit," "umask" i "niceness" bêd±
+zainicjowane warto¶ciami podanymi (o ile s± podane) w polu
+.I gecos
+pliku
+.IR passwd .
+Patrz tak¿e podrêcznik
+.BR passwd (5).
+.\"
+.IP "SU_NAME (napis)"
+Przypisuje nazwê polecenia do uruchomionego "su -". Na przyk³ad, je¶li
+parametr ten jest zdefiniowany jako "su", to polecenie
+.BR ps (1)
+poka¿e uruchomione polecenie jako "-su". Je¶li parametr ten jest
+niezdefiniowany, to
+.BR ps (1)
+poka¿e nazwê faktycznie wykonywanej pow³oki, np. co¶ w rodzaju "-sh".
+.\"
+.IP "SULOG_FILE (napis)"
+Pokazuje pe³n± nazwê ¶cie¿kow± pliku, w którym rejestrowane jest wykorzystanie
+.BR su .
+Je¶li parametr ten nie jest okre¶lony, to rejestrowanie nie jest wykonywane.
+Poniewa¿ polecenie
+.B su
+mo¿e byæ u¿ywane podczas prób uwierzytelnienia has³a, do odnotowywania
+u¿ycia
+.B su
+powinny byæ u¿ywane albo niniejsza opcja
+albo
+.IR syslog .
+Zobacz te¿ opis SYSLOG_SU_ENAB.
+.\"
+.IP "SU_WHEEL_ONLY (logiczna)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "SYSLOG_SG_ENAB (logiczna)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "SYSLOG_SU_ENAB (logiczna)"
+Je¿eli ma warto¶æ
+.IR yes ,
+za¶ program
+.B login
+zosta³ skompilowany z obs³ug±
+.IR syslog ,
+to wszelkie dzia³ania
+.B su
+bêd± rejestrowane za pomoc±
+.IR syslog .
+Zobacz te¿ opis SULOG_FILE.
+.\"
+.IP "TTYGROUP (napis lub liczba)"
+Grupa (w³a¶cicielska) terminala inicjowana jest na nazwê b±d¼ numer tej grupy.
+Jeden z dobrze znanych ataków polega na wymuszeniu sekwencji kontrolnych
+terminala na linii terminalowej innego u¿ytkownika. Problemu tego mo¿na
+unikn±æ wy³±czaj±c prawa zezwalaj±ce innym u¿ytkownikom na dostêp do linii
+terminalowej, ale niestety zapobiega to równie¿ dzia³aniu programów takich
+jak
+.BR write .
+Innym rozwi±zaniem jest pos³u¿enie siê tak± wersj± programu
+.BR write ,
+która odfiltrowuje potencjalnie niebezpieczne sekwencje znaków. Nastêpnie
+programowi nale¿y przyznaæ rozszerzone prawa dostêpu (SGID) dla specjalnej
+grupy, ustawiæ grupê w³a¶cicieli terminala na tê grupê i nadaæ prawa dostêpu
+\fI0620\fR do linii. Definicja TTYGROUP powsta³a do obs³ugi tej w³a¶nie
+sytuacji.
+Je¶li pozycja ta nie jest zdefiniowana, to grupa terminala inicjowana jest
+na numer grupy u¿ytkownika.
+Zobacz tak¿e TTYPERM.
+.\"
+.IP "TTYPERM (liczba)"
+T± warto¶ci± inicjowane s± prawa terminala logowania. Typowymi warto¶ciami s±
+\fI0622\fR zezwalaj±ce innym na pisanie do linii lub \fI0600\fR zabezpieczaj±ce
+liniê przed innymi u¿ytkownikami. Je¿eli nie podano tego parametru, to prawa
+dostêpu do terminala zostan± zainicjowane warto¶ci± \fI0622\fR. Zobacz te¿
+TTYGROUP.
+.\"
+.IP "TTYTYPE_FILE (napis)"
+Okre¶la pe³n± nazwê ¶cie¿kow± pliku przypisuj±cego typy terminali do linii
+terminalowych. Ka¿dy z wierszy tego pliku zawiera rozdzielone bia³ym znakiem
+typ i liniê terminala. Na przyk³ad:
+.nf
+.sp
+.ft I
+ vt100\0 tty01
+ wyse60 tty02
+ \0\0.\0\0\0 \0\0.
+ \0\0.\0\0\0 \0\0.
+ \0\0.\0\0\0 \0\0.
+.ft R
+.sp
+.fi
+Informacja ta s³u¿y do inicjowania zmiennej ¶rodowiska TERM. Wiersz
+rozpoczynaj±cy siê znakiem # bêdzie traktowany jak komentarz. Je¿eli nie
+podano tego parametru lub plik nie istnieje albo nie znaleziono w nim
+linii terminala, to zmienna TERM nie zostanie ustawiona.
+.\"
+.IP "UID_MAX (liczba)"
+XXX powinno zostaæ udokumentowane.
+.IP "UID_MIN (liczba)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.IP "ULIMIT (d³uga liczba)"
+Warto¶ci± t± inicjowany jest limit wielko¶ci pliku. Cecha ta obs³ugiwana
+jest wy³±cznie w systemach posiadaj±cych
+.IR ulimit ,
+np. System V. Je¶li nie podano, to limit wielko¶ci pliku zostanie ustalony
+na pewn± wielk± warto¶æ.
+.\"
+.IP "UMASK (liczba)"
+T± warto¶ci± inicjowana jest maska praw dostêpu. Nie podana, ustawia mask±
+praw na zero.
+.\"
+.IP "USERDEL_CMD (napis)"
+XXX powinno zostaæ udokumentowane.
+.\"
+.SH POWI¡ZANIA
+Poni¿sze zestawienie pokazuje, które z programów wchodz±cych w sk³ad pakietu
+shadow wykorzystuj± jakie parametry.
+.na
+.IP login 12
+CONSOLE DIALUPS_CHECK_ENAB ENV_HZ ENV_SUPATH ENV_TZ ERASECHAR FAILLOG_ENAB
+FTMP_FILE HUSHLOGIN_FILE KILLCHAR LASTLOG_ENAB LOG_UNKFAIL_ENAB
+MAIL_CHECK_ENAB MAIL_DIR MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB
+QUOTAS_ENAB TTYPERM TTYTYPE_FILE ULIMIT UMASK
+.IP newusers 12
+PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE UMASK
+.IP passwd 12
+OBSCURE_CHECKS_ENAB PASS_MIN_LEN
+.IP pwconv 12
+PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
+.IP su 12
+ENV_HZ ENV_SUPATH ENV_TZ HUSHLOGIN_FILE MAIL_CHECK_ENAB MAIL_DIR
+MOTD_FILE NOLOGIN_STR QUOTAS_ENAB SULOG_FILE SYSLOG_SU_ENAB
+.IP sulogin 12
+ENV_HZ ENV_SUPATH ENV_TZ MAIL_DIR QUOTAS_ENAB TTYPERM
+.ad
+.SH B£ÊDY
+Niektóre z obs³ugiwanych parametrów konfiguracyjnych pozosta³y
+nieopisane w niniejszym podrêczniku.
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR passwd (5),
+.BR faillog (5),
+.BR porttime (5),
+.BR faillog (8)
+.SH AUTORZY
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.br
+Chip Rosenthal (chip@unicom.com)
diff --git a/current/man/pl/logoutd.8 b/current/man/pl/logoutd.8
new file mode 100644
index 00000000..d9f8f28a
--- /dev/null
+++ b/current/man/pl/logoutd.8
@@ -0,0 +1,50 @@
+.\" {PTM/WK/1999-09-17}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH LOGOUTD 8
+.SH NAZWA
+logoutd \- wymuszenie ograniczeñ czasu logowania
+.SH SK£ADNIA
+.B logoutd
+.SH OPIS
+.B logoutd
+wymusza ograniczenia portów i czasów logowania podane w
+.IR /etc/porttime .
+.B logoutd
+powinno byæ uruchamiane z \fI/etc/rc\fR.
+Okresowo przegl±dany jest plik \fI/etc/utmp\fR. Sprawdzana jest ka¿da nazwa
+u¿ytkownika, by móc stwierdziæ czy posiada on zezwolenie na pracê w bie¿±cym
+czasie na danym porcie.
+Ka¿da sesja pracy (logowania) naruszaj±ca ograniczenia zawarte
+w \fI/etc/porttime\fR jest koñczona.
+.SH PLIKI
+.IR /etc/porttime " - zezwolenia dla logowania na portach"
+.br
+.IR /etc/utmp " - bie¿±ce sesje pracy"
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/mkpasswd.8 b/current/man/pl/mkpasswd.8
new file mode 100644
index 00000000..815ea6ac
--- /dev/null
+++ b/current/man/pl/mkpasswd.8
@@ -0,0 +1,80 @@
+.\" {PTM/WK/1999-09-16}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: mkpasswd.8,v 1.1 1999/09/16 07:11:24 wojtek2 Exp $
+.\"
+.TH MKPASSWD 1
+.SH NAZWA
+mkpasswd \- aktualizuj pliki baz passwd i group
+.SH SK£ADNIA
+\fBmkpasswd\fR [\fB-fvgps\fR] \fIplik\fR
+.SH OPIS
+.B mkpasswd
+czyta plik w formacie okre¶lonym przez flagi i konwertuje go postaci
+odpowiedniego pliku bazy danych.
+Wymienione pliki baz danych u¿ywane s± do poprawienia wydajno¶ci dostêpu
+w systemach o du¿ej liczbie u¿ytkowników.
+Pliki wynikowe otrzymaj± nazwy \fIplik\fR.dir i \fIplik\fR.pag.
+.PP
+Opcja \fB-f\fR powoduje, ¿e \fBmkpasswd\fR ignoruje istnienie plików
+wynikowych i nadpisuje je.
+Normalnie \fBmkpasswd\fR skar¿y siê na istnienie plików wynikowych
+i koñczy pracê.
+.PP
+Opcja \fB-v\fR powoduje wy¶wietlanie informacji o ka¿dym konwertowanym
+rekordzie oraz komunikatu koñcowego.
+.PP
+Opcja \fB-g\fR traktuje plik ¼ród³owy tak, jak gdyby by³ on w formacie
+pliku \fI/etc/group\fR.
+Przy po³±czeniu z opcj± \fB-s\fR u¿ywany jest format pliku \fI/etc/gshadow\fR.
+.PP
+Opcja \fB-p\fR traktuje plik ¼ród³owy tak, jak gdyby by³ on w formacie
+pliku \fI/etc/passwd\fR.
+Jest to opcja domy¶lna.
+Przy po³±czeniu z opcj± \fB-s\fR u¿ywany jest format pliku \fI/etc/shadow\fR.
+.SH PRZESTROGI
+U¿ycie wiêcej ni¿ jednego pliku bazy ogranicza siê do systemów posiadaj±cych
+bibliotekê baz danych NDBM. Mo¿e zatem nie byæ dostêpne w ka¿dym systemie.
+.SH UWAGA
+Poniewa¿ wiêkszo¶æ poleceñ jest w stanie aktualizowaæ pliki bazy danych
+podczas dokonywania zmian, \fBmkpasswd\fR potrzebne jest jedynie
+do ponownego utworzenia usuniêtego lub zepsutego pliku bazy.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - chroniona informacja o u¿ytkownikach"
+.br
+.IR /etc/group " - informacja o grupach"
+.br
+.IR /etc/gshadow " - chroniona informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR passwd (5),
+.BR group (5),
+.BR shadow (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/newgrp.1 b/current/man/pl/newgrp.1
new file mode 100644
index 00000000..eaf3b18e
--- /dev/null
+++ b/current/man/pl/newgrp.1
@@ -0,0 +1,87 @@
+.\" {PTM/WK/1999-09-15}
+.\" Copyright 1991, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: newgrp.1,v 1.2 1999/09/25 20:07:46 wojtek2 Exp $
+.\"
+.TH NEWGRP 1
+.SH NAZWA
+newgrp \- zmieñ identyfikator grupy
+.br
+sg \- wykonaj polecenie przy innym ID grupy
+.SH SK£ADNIA
+.BR newgrp " [" - ]
+.RI [ grupa ]
+.br
+.BR sg " [" - ]
+.RI [ grupa
+.RB [ -c
+.IR polecenie ]]
+.SH OPIS
+.B newgrp
+s³u¿y do zmiany bie¿±cego identyfikatora grupy (GID) podczas sesji logowania.
+Je¿eli podano opcjonaln± flagê \fB\-\fR, to ¶rodowisko u¿ytkownika zostanie
+ponownie zainicjowane, tak jak wówczas, gdy u¿ytkownik siê loguje. Je¿eli nie
+u¿yto flagi \fB\-\fR, to bie¿±ce ¶rodowisko, ³±cznie z bie¿±cym katalogiem
+roboczym, pozostaje bez zmian.
+.PP
+.B newgrp
+zmienia bie¿±cy faktyczny identyfikator grupy na identyfikator danej grupy
+lub, je¶li nie podano nazwy grupy, na identyfikator grupy domy¶lnej, podanej
+w \fI/etc/passwd\fR.
+Je¿eli grupa posiada has³o, za¶ u¿ytkownik nie ma has³a b±d¼ nie jest jej
+cz³onkiem, to zostanie poproszony o podanie has³a.
+Je¿eli has³o grupy jest puste za¶ u¿ytkownik nie jest jej cz³onkiem, to
+efektem bêdzie odmowa dostêpu.
+.PP
+Polecenie
+.B sg
+dzia³a podobnie do \fBnewgrp\fR, lecz nie zastêpuje pow³oki u¿ytkownika,
+wiêc po zakoñczeniu \fBsg\fR powracasz do swego poprzedniego identyfikatora
+grupy.
+.B sg
+przyjmuje tak¿e pojedyncze polecenie. Podane polecenie zostanie wykonane
+w pow³oce Bourne'a i musi byæ umieszczone w cudzys³owach.
+.\" enclosed in quotes.
+.SH PRZESTROGI
+Niniejsza wersja \fBnewgrp\fR posiada wiele opcji kompilacji,
+z których tylko czê¶æ mo¿e byæ u¿yteczna w konkretnej instalacji.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/group " - informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR id (1),
+.BR su (1)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/newusers.8 b/current/man/pl/newusers.8
new file mode 100644
index 00000000..077da942
--- /dev/null
+++ b/current/man/pl/newusers.8
@@ -0,0 +1,69 @@
+.\" {PTM/WK/1999-09-15}
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: newusers.8,v 1.3 1999/09/25 20:07:47 wojtek2 Exp $
+.\"
+.TH NEWUSERS 8
+.SH NAZWA
+newusers - wsadowa aktualizacja i tworzenie nowych u¿ytkowników
+.SH SK£ADNIA
+.B newusers
+.RI [ nowi_u¿ytkownicy ]
+.SH OPIS
+\fBnewusers\fR odczytuje plik zawieraj±cy pary: nazwa u¿ytkownika i podane
+jawnym tekstem has³o. Odczytan± informacjê wykorzystuje do aktualizacji grupy
+istniej±cych u¿ytkowników lub utworzenia nowych.
+Ka¿dy wiersz pliku posiada taki sam format jak standardowy plik hase³ (patrz
+\fBpasswd\fR(5)), z nastêpuj±cymi wyj±tkami:
+.IP "\fIpw_passwd\fR" 10
+To pole zostanie zakodowane i u¿yte jako nowa warto¶æ zakodowanego has³a.
+.IP "\fIpw_age\fR"
+Dla chronionych hase³ (shadow) pole zostanie zignorowane je¶li u¿ytkownik ju¿
+istnieje.
+.IP "\fIpw_gid\fR"
+Pole to mo¿e zawieraæ nazwê istniej±cej grupy. Dany u¿ytkownik zostanie
+wówczas dodany do jej cz³onków. Je¿eli podano numeryczny identyfikator
+nieistniej±cej grupy, to zostanie za³o¿ona nowa grupa o tym identyfikatorze.
+.IP "\fIpw_dir\fR"
+Zostanie wykonane sprawdzenie czy istnieje katalog o tej nazwie. Je¿eli nie,
+to bêdzie on utworzony. W³a¶cicielem zostanie ustanowiony tworzony
+(lub aktualizowany) u¿ytkownik. Grupa katalogu zostanie ustawiona na grupê
+u¿ytkownika.
+.PP
+Polecenie to przeznaczone jest do u¿ytku w du¿ych systemach, gdzie aktualizuje
+siê wiele kont naraz.
+.SH PRZESTROGI
+.\" Po u¿yciu \fBnewusers\fR musi zostaæ wykonane polecenie \fImkpasswd\fR,
+.\" aktualizuj±ce pliki DBM hase³ (DBM password files).
+Plik ¼ród³owy, zawieraj±cy niezakodowane has³a, musi byæ chroniony.
+.SH ZOBACZ TAK¯E
+.\" mkpasswd(8), passwd(1), useradd(1)
+.BR passwd (1),
+.BR useradd (8)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/passwd.1 b/current/man/pl/passwd.1
new file mode 100644
index 00000000..6e69c963
--- /dev/null
+++ b/current/man/pl/passwd.1
@@ -0,0 +1,201 @@
+.\" {PTM/WK/1999-09-20}
+.\" Copyright 1989 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH PASSWD 1
+.SH NAZWA
+passwd \- zmieñ has³o u¿ytkownika
+.SH SK£ADNIA
+.B passwd
+.RB [ -f | -s ]
+.RI [ nazwa ]
+.br
+.B passwd
+.RB [ -g ]
+.RB [ -r | R ]
+.I grupa
+.br
+.B passwd
+.RB [ -x
+.IR max ]
+.RB [ -n
+.IR min ]
+.RB [ -w
+.IR ostrze¿ ]
+.RB [ -i
+.IR nieakt ]
+.I nazwa
+.br
+.B passwd
+.RB { -l | -u | -d | -S }
+.I nazwa
+.SH OPIS
+\fBpasswd\fR zmienia has³a kont u¿ytkowników i grup.
+Zwyk³y u¿ytkownik mo¿e zmieniæ wy³±cznie has³o w³asnego konta, superu¿ytkownik
+mo¿e zmieniaæ has³a dowolnych kont.
+Administrator grupy mo¿e zmieniæ has³o tej grupy.
+\fBpasswd\fR zmienia tak¿e informacje o koncie, takie jak pe³na nazwa
+u¿ytkownika, jego pow³oka zg³oszeniowa (logowania) czy daty i interwa³y dotycz±ce
+wa¿no¶ci has³a.
+.SS Zmiany has³a
+Na pocz±tku u¿ytkownik pytany jest o stare, dotychczasowe has³o, je¶li takie
+istnieje. Has³o to jest kodowane i porównywane z przechowywanym has³em.
+U¿ytkownik ma tylko jedn± próbê na wprowadzenie poprawnego has³a.
+Superu¿ytkownikowi zezwala siê na pominiêcie tego kroku, zatem mog± byæ
+zmienione has³a, których zapomniano.
+.PP
+Po wprowadzeniu has³a, sprawdzana jest informacja o jego wieku, by stwierdziæ
+czy u¿ytkownikowi wolno w danym czasie zmieniæ has³o.
+Je¿eli nie, to \fBpasswd\fR odmawia zmiany has³a i koñczy pracê.
+.PP
+Nastêpnie u¿ytkownik proszony jest o nowe, zastêpuj±ce dotychczasowe, has³o
+Has³o podlega sprawdzeniu jego zawi³o¶ci. Jako ogóln± wskazówk± mo¿na podaæ,
+¿e has³a powinny sk³adaæ siê z 6 do 8 znaków, zawieraj±c po jednym lub wiêcej
+znaków z ka¿dej z poni¿szych kategorii:
+.IP "" .5i
+ma³e litery alfabetu
+.IP "" .5i
+du¿e litery alfabetu
+.IP "" .5i
+cyfry od 0 do 9
+.IP "" .5i
+znaki interpunkcyjne
+.PP
+Nale¿y uwa¿aæ, by nie u¿yæ domy¶lnych systemowych znaków akcji erase lub kill.
+\fBpasswd\fR odrzuci ka¿de niedostatecznie skomplikowane has³o.
+.PP
+Je¶li has³o zostanie przyjête, to \fBpasswd\fR prosi o jego powtórzenie
+i porównuje drugi wpis z pierwszym.
+Oba wpisy musz± byæ takie same by has³o zosta³o zmienione.
+.SS Has³a grup
+Je¿eli pos³u¿ono siê opcj± \fB-g\fR, to zmieniane jest has³o podanej grupy.
+U¿ytkownik powinien byæ albo superu¿ytkownikiem albo administratorem tej grupy.
+Nie wystêpuje pytanie o bie¿±ce has³o grupy.
+Do usuwania bie¿±cego has³a danej grupy s³u¿y opcja \fB-g\fR w po³±czeniu
+z \fB-r\fR. Pozwala to na dostêp do grupy tylko jej cz³onkom.
+Opcja \fB-R\fR w po³±czeniu z \fR-g\fR ogranicza dostêp do grupy wszystkim
+u¿ytkownikom.
+.SS Informacja o wa¿no¶ci konta
+Superu¿ytkownik mo¿e zmieniaæ informacjê o wieku konta pos³uguj±c siê opcjami
+\fB-x\fR, \fB-n\fR, \fB-w\fR oraz \fB-i\fR.
+Opcja \fB-x\fR s³u¿y do ustawiania maksymalnej liczby dni, przez jakie has³o
+pozostaje wa¿ne.
+Po up³ywie \fImax\fR dni, has³o musi byæ zmienione.
+Opcja \fB-n\fR ustawia minimaln± liczbê dni, jakie musz± up³yn±æ zanim has³o
+bêdzie mog³o byæ zmienione.
+U¿ytkownik nie otrzyma zezwolenia na zmianê has³a przed up³ywem \fImin\fR dni.
+Opcja \fB-w\fR s³u¿y do ustawienia liczby dni przed up³ywem terminu wa¿no¶ci
+has³a, przez które u¿ytkownik bêdzie otrzymywa³ ostrze¿enie mówi±ce mu, ile dni
+pozosta³o do tej daty. Ostrze¿enia zaczn± pojawiaæ siê \fIostrze¿\fR dni przed
+up³ywem wa¿no¶ci has³a.
+Opcja \fB-i\fR (nieaktywno¶æ) s³u¿y do wy³±czania konta po up³ywie zadanej
+liczby dni po wyga¶niêciu has³a.
+Po up³ywie \fInieakt\fR dni od przeterminowania has³a u¿ytkownik nie mo¿e ju¿
+korzystaæ z konta.
+.SS Utrzymywanie i konserwacja konta
+Konta u¿ytkowników mog± byæ blokowane i odblokowywane przy pomocy flag \fB-l\fR
+i \fB-u\fR.
+Opcja \fB-l\fR wy³±cza konto zmieniaj±c jego has³o na warto¶æ nieodpowiadaj±c±
+¿adnemu mo¿liwemu zakodowanemu has³u.
+Opcja \fB-u\fR ponownie udostêpnia konto przywracaj±c uprzedni± warto¶æ has³a.
+.PP
+Stan konta mo¿na uzyskaæ przy pomocy opcji \fB-S\fR.
+Informacja o stanie sk³ada siê z 6 czê¶ci.
+Pierwsza wskazuje, czy konto u¿ytkownika jest zablokowane (L) (locked),
+nie posiada has³a (NP) (no password) lub ma funkcjonalne has³o (P) (password).
+Druga czê¶æ podaje datê ostatniej zmiany has³a.
+nastêpne cztery to minimalny wiek, maksymalny wiek, okres ostrzegania i okres
+nieaktywno¶ci has³a.
+.SS Podpowiedzi dotycz±ce hase³ u¿ytkownika
+Bezpieczeñstwo has³a zale¿y od si³y algorytmu koduj±cego oraz rozmiaru
+klucza.
+Metoda kodowania u¿ywana w Systemie \fB\s-2UNIX\s+2\fR oparta jest o algorytm
+NBS DES i jest bardzo bezpieczna.
+Rozmiar klucza zale¿y od losowo¶ci wybranego has³a.
+.PP
+Naruszenia bezpieczeñstwa hase³ wynikaj± zwykle z beztroski przy wyborze lub
+przechowywaniu has³a.
+Z tego powodu powiniene¶ wybraæ has³o nie wystêpuj±ce w s³owniku. Has³o nie
+powinno te¿ byæ poprawn± nazw±, imieniem, nazwiskiem, numerem prawa jazdy,
+dat± urodzenia czy elementem adresu.
+Wszystkie z powy¿szych mog± byæ u¿yte do odgadniêcia has³a i naruszenia
+bezpieczeñstwa systemu.
+.PP
+Has³o musi byæ ³atwe do zapamiêtania, tak by nie byæ zmuszonym do jego
+zapisywania na kartce. Mo¿na to osi±gn±æ sklejaj±c ze sob± dwa krótkie s³owa,
+ze wstawionym pomiêdzy nie znakiem specjalnym lub cyfr±.
+Na przyk³ad, Pass%word, Lew7konia.
+.PP
+Inna metoda konstrukcji has³a polega na wyborze ³atwego do zapamiêtania zdania
+(np. z literatury) i wyborze pierwszej b±d¼ ostatniej litery ka¿dego wyrazu.
+Przyk³adem tego jest
+.IP "" .5i
+Ask not for whom the bell tolls.
+.PP
+co daje
+.IP "" .5i
+An4wtbt,
+.PP
+albo te¿
+.IP "" .5i
+A czy znasz Ty, bracie m³ody
+.PP
+co daje
+.IP "" .5i
+A3zTbm.
+.PP
+W zasadzie mo¿esz byæ pewien, ¿e niewielu crackerów bêdzie mieæ takie has³o
+w swoim s³owniku. Powiniene¶ jednak wybraæ w³asn± metodê konstrukcji hase³
+a nie polegaæ wy³±cznie na opisanych tutaj.
+.SS Uwagi o has³ach grup
+Has³a grup s± nieod³±cznym problemem bezpieczeñstwa, gdy¿ do ich znajomo¶ci
+uprawniona jest wiêcej ni¿ jedna osoba.
+Grupy s± jednak u¿ytecznym narzêdziem pozwalaj±cym na wspó³pracê miêdzy
+ró¿nymi u¿ytkownikami.
+.SH PRZESTROGI
+Mog± nie byæ obs³ugiwane wszystkie opcje.
+Sprawdzanie z³o¿ono¶ci has³a mo¿e ró¿niæ siê w ró¿nych instalacjach. Zachêca
+siê u¿ytkownika do wyboru tak skomplikowanego has³a, z jakim bêdzie mu
+wygodnie.
+U¿ytkownicy mog± nie móc zmieniæ has³a w systemie przy w³±czonym NIS, je¶li
+nie s± zalogowani do serwera NIS.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - zakodowane has³a u¿ytkowników"
+.SH ZOBACZ TAK¯E
+.BR passwd (3),
+.BR shadow (3),
+.BR group (5),
+.BR passwd (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/passwd.5 b/current/man/pl/passwd.5
new file mode 100644
index 00000000..e4bcad8e
--- /dev/null
+++ b/current/man/pl/passwd.5
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1993 Michael Haardt (u31b3hs@pool.informatik.rwth-aachen.de), Fri Apr 2 11:32:09 MET DST 1993
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.\" Modified Sun Jul 25 10:46:28 1993 by Rik Faith (faith@cs.unc.edu)
+.\" Modified Sun Aug 21 18:12:27 1994 by Rik Faith (faith@cs.unc.edu)
+.\" Modified Sun Jun 18 01:53:57 1995 by Andries Brouwer (aeb@cwi.nl)
+.\"
+.\" Polish translation nov.1996 piotr.pogorzelski@ippt.gov.pl
+.\"
+.TH PASSWD 5 "24 Czerwiec 1993" "Linux" "Podrêcznik programisty linuxowego"
+.SH NAZWA
+passwd \- plik passwd definiuj±cy u¿ytkowników systemu
+.SH OPIS
+Plik
+.B passwd
+jest plikiem tekstowym ASCII, który zawiera listê u¿ytkowników systemu
+oraz has³a jakich musz± u¿ywaæ aby otrzymaæ dostêp do systemu.
+Ka¿dy powinien móc odczytaæ informacje z pliku passwd (poniewa¿ has³a
+w tym pliku s± zakodowane jest to poprawne) lecz prawo do modyfikacji
+pliku powinien mieæ tylko administrator.
+Dodaj±c nowego u¿ytkownika nale¿y pole przeznaczone na has³o pozostawiæ puste
+i u¿yæ programu \fBpasswd\fP(1). Gwiazdka lub inny pojedynczy znak w polu
+has³a oznacza, ze u¿ytkownik nie mo¿e dostaæ siê do systemu przez \fBlogin\fP(1).
+Je¶li g³ówny system plików jest na ram dysku (/dev/ram) nale¿y
+plik passwd skopiowaæ na dyskietkê przechowuj±c± g³ówny system plików
+przed zamkniêciem systemu. Trzeba równie¿ sprawdziæ prawa dostêpu do.
+Je¶li trzeba utworzyæ grupê u¿ytkowników, ich identyfikatory grupy
+GID musz± byæ równe oraz musi istnieæ odpowiednia pozycja w pliku
+\fI/etc/group\fP, lub grupa nie bêdzie istnia³a.
+.PP
+Ka¿da pozycja zajmuje jeden wiersz w formacie:
+.sp
+login_name:has³o:UID:GID:imie_nazwisko:katalog:pow³oka
+.RS
+.RE
+.sp
+Krótki opis poszczególnych pól:
+.sp
+.RS
+.TP 1.0in
+.I login_name
+nazwa u¿ytkownika w systemie (radzê u¿ywaæ ma³ych liter).
+.TP
+.I has³o
+zakodowane has³o u¿ytkownika.
+.TP
+.I UID
+identyfikator u¿ytkownika (liczbowo).
+.TP
+.I GID
+identyfikator grupy (liczbowo).
+.TP
+.I imiê_nazwisko
+Opisowa nazwa u¿ytkownika, zwykle imiê i nazwisko (wykorzystywane
+przez programy pocztowe).
+.TP
+.I katalog
+katalog macierzysty ($HOME) u¿ytkownika.
+.TP
+.I pow³oka
+program jaki uruchomiæ po wej¶ciu u¿ytkownika do systemu.
+(je¶li pusty u¿yj /bin/sh, je¶li istnieje /etc/shells i
+dana pow³oka nie jest tam wymieniona, u¿ytkownik nie bêdzie móg³
+dostaæ siê do systemu wykorzystuj±c protokó³ ftp).
+.RE
+.SH PLIKI
+.I /etc/passwd
+.SH "ZOBACZ TAK¯E"
+.BR passwd "(1), " login "(1), " group (5)
diff --git a/current/man/pl/porttime.5 b/current/man/pl/porttime.5
new file mode 100644
index 00000000..83f0af6a
--- /dev/null
+++ b/current/man/pl/porttime.5
@@ -0,0 +1,81 @@
+.\" {PTM/WK/1999-09-17}
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH PORTTIME 5
+.SH NAZWA
+porttime \- plik czasów dostêpu do portów
+.SH OPIS
+.I porttime
+zawiera listê urz±dzeñ tty, nazw u¿ytkowników i dozwolonych czasów logowania.
+.PP
+Ka¿da pozycja sk³ada siê z trzech, rozdzielonych dwukropkiem, pól.
+Pierwsze pole zawiera listê oddzielonych przecinkami urz±dzeñ tty lub
+gwiazdkê, wskazuj±c±, ¿e pozycja ta pasuje do wszystkich urz±dzeñ tty.
+Drugie pole zawiera listê oddzielonych przecinkami nazw u¿ytkowników lub
+gwiazdkê, wskazuj±c±, ¿e pozycja dotyczy wszystkich u¿ytkowników.
+Trzecie pole jest list± oddzielonych przecinkami dozwolonych czasów dostêpu.
+.PP
+Ka¿da pozycja czasu dostêpu sk³ada siê z zera lub wiêcej dni tygodnia,
+skróconych do \fBSu\fR, \fBMo\fR, \fBTu\fR, \fBWe\fR, \fBTh\fR, \fBFr\fR
+i \fBSa\fR, po których nastêpuje para rozdzielonych my¶lnikiem czasów.
+Do okre¶lenia dni roboczych (od poniedzia³ku do pi±tku) mo¿e byæ u¿yty
+skrót \fBWk\fR. Skrót \fBAl\fR oznacza ka¿dy dzieñ. Je¿eli nie podano dni
+tygodnia przyjmowane jest \fBAl\fR.
+.SH PRZYK£ADY
+Poni¿szy wpis zezwala u¿ytkownikowi \fBjfh\fR na dostêp do ka¿dego portu
+w dni robocze od godziny 9-tej do 17-tej.
+.br
+.sp 1
+ *:jfh:Wk0900-1700
+.br
+.sp 1
+Poni¿sze pozycje pozwalaj± na dostêp do konsoli (/dev/console) wy³±cznie
+u¿ytkownikom \fBroot\fR i \fBoper\fR - w dowolnym czasie.
+Przyk³ad ten pokazuje, ¿e plik \fI/etc/porttime\fR stanowi uporz±dkowan±
+listê czasów dostêpu. Ka¿dy inny u¿ytkownik bêdzie pasowa³ do drugiej pozycji
+listy, nie zezwalaj±cej na dostêp w ¿adnym czasie.
+.br
+.sp 1
+ console:root,oper:Al0000-2400
+.br
+ console:*:
+.br
+.sp 1
+Poni¿szy wpis zezwala na dostêp do dowolnego portu u¿ytkownikowi \fBgames\fR
+poza godzinami pracy.
+.br
+.sp 1
+ *:games:Wk1700-0900,SaSu0000-2400
+.br
+.sp 1
+.SH PLIKI
+.IR /etc/porttime " - plik zawieraj±cy czasy dostêpu do portów"
+.SH ZOBACZ TAK¯E
+.BR login (1)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/pw_auth.3 b/current/man/pl/pw_auth.3
new file mode 100644
index 00000000..ddebc0c1
--- /dev/null
+++ b/current/man/pl/pw_auth.3
@@ -0,0 +1,152 @@
+.\" {PTM/WK/1999-09-15}
+.\" Copyright 1992 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: pw_auth.3,v 1.1 1999/09/16 07:11:23 wojtek2 Exp $
+.\"
+.TH PWAUTH 3
+.SH NAZWA
+pwauth \- procedury uwierzytelniania hase³ zdefiniowane przez administratora
+.SH SK£ADNIA
+.B #include <pwauth.h>
+.PP
+.B int pw_auth (char
+.I *command,
+.B char
+.I *user,
+.B int
+.I reason,
+.B char
+.IB *input) ;
+.SH OPIS
+.B pw_auth
+wywo³uje funkcje zdefiniowane przez administratora dla danego u¿ytkownika.
+.PP
+\fIcommand\fR jest nazw± programu uwierzytelniania (autentykacji).
+Jest ona otrzymywana z informacji zawartej pliku hase³ u¿ytkowników.
+Odpowiedni ³añcuch (z pola has³a) zawiera jedn± lub wiêcej, rozdzielonych
+¶rednikami, nazw plików wykonywalnych.
+Programy zostan± wykonane w zadanej kolejno¶ci.
+Dla ka¿dej z przyczyn (reason) podanych ni¿ej podane s± argumenty wiersza
+poleceñ.
+.PP
+\fIuser\fR jest nazw± sprawdzanego u¿ytkownika, w postaci podanej w pliku
+\fI/etc/passwd\fR.
+Pozycje opisuj±ce u¿ytkowników indeksowane s± nazw± u¿ytkownika.
+Pozwala to na istnienie powtarzaj±cych siê identyfikatorów (UID). Ka¿da
+z ró¿nych nazw u¿ytkownika o tym samym identyfikatorze mo¿e
+posiadaæ inny program i informacjê autentykuj±c±.
+.PP
+Ka¿da z dopuszczalnych przyczyn autentykacji obs³ugiwana jest w potencjalnie
+ró¿ny sposób.
+Do komunikacji z u¿ytkownikiem dostêpne s± standardowe deskryptory plików
+0, 1 i 2, chyba ¿e wspomniano inaczej.
+Do ustalenia to¿samo¶ci u¿ytkownika wykonuj±cego ¿±danie uwierzytelnienia
+mo¿e zostaæ u¿yty rzeczywisty identyfikator.
+Przyczyna (\fIreason\fR) jest jedn± z
+.IP \fBPW_SU\fR 1i
+Wykonaj uwierzytelnienie dla bie¿±cego rzeczywistego identyfikatora u¿ytkownika
+próbuj±c prze³±czyæ rzeczywisty ID na podanego u¿ytkownika.
+Program uwierzytelniaj±cy zostanie wywo³any z opcj± \fB-s\fR poprzedzaj±c±
+nazwê u¿ytkownika.
+.IP \fBPW_LOGIN\fR 1i
+Wykonaj uwierzytelnienie dla danego u¿ytkownika tworz±c now± sesjê pracy
+(loginow±). Program uwierzytelniaj±cy zostanie wywo³any z opcj± \fB-l\fR,
+po której wyst±pi nazwa u¿ytkownika.
+.IP \fBPW_ADD\fR 1i
+Utwórz nowy wpis dla danego u¿ytkownika.
+Pozwala to programowi uwierzytelniania na zainicjowanie miejsca dla nowego
+u¿ytkownika.
+Program zostanie wywo³any z opcj± \fB-a\fR, po której wyst±pi nazwa u¿ytkownika.
+.IP \fBPW_CHANGE\fR 1i
+Zmieñ istniej±cy wpis dla danego u¿ytkownika.
+Pozwala to na programowi uwierzytelniaj±cemu na zmianê informacji autentykuj±cej
+dla istniej±cego u¿ytkownika.
+Program zostanie wywo³any z opcj± \fB-c\fR poprzedzaj±c± nazwê u¿ytkownika.
+.IP \fBPW_DELETE\fR 1i
+Usuñ informacjê autentykuj±c± dla danego u¿ytkownika.
+Pozwala programowi uwierzytelniania na odzyskanie miejsca po u¿ytkowniku, który
+nie bêdzie ju¿ identyfikowany przy u¿yciu tego programu.
+Program uwierzytelniania zostanie wywo³any z opcj± \fB-d\fR,
+po której wyst±pi nazwa u¿ytkownika.
+.IP \fBPW_TELNET\fR 1i
+Wykonaj uwierzytelnianie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy
+polecenia \fBtelnet\fR.
+Program zostanie wywo³any z opcj± \fB-t\fR, po której wyst±pi nazwa u¿ytkownika.
+.IP \fBPW_RLOGIN\fR 1i
+Wykonaj uwierzytelnienie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy
+polecenia \fBrlogin\fR.
+Program zostanie wywo³any z opcj± \fB-r\fR, po której wyst±pi nazwa u¿ytkownika.
+.IP \fBPW_FTP\fR 1i
+Wykonaj uwierzytelnienie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy
+polecenia \fBftp\fR.
+Program uwierzytelniania zostanie wywo³any z opcj± \fB-f\fR,
+po której wyst±pi nazwa u¿ytkownika.
+Do komunikacji z u¿ytkownikiem NIE s± dostêpne standardowe deskryptory plików.
+Deskryptor standardowego wej¶cia zostanie pod³±czony do procesu macierzystego,
+za¶ pozosta³e dwa deskryptory plików dostan± pod³±czone do \fI/dev/null\fR.
+Funkcja \fBpw_auth\fR bêdzie potokowaæ pojedynczy wiersz danych do programu
+uwierzytelniania pos³uguj±c siê deskryptorem 0.
+.IP \fBPW_REXEC\fR 1i
+Wykonaj uwierzytelnienie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy
+polecenia \fIrexec\fR.
+Program zostanie wywo³any z opcj± \fB-x\fR, po której wyst±pi nazwa u¿ytkownika.
+Do komunikacji ze zdalnym u¿ytkownikiem NIE s± dostêpne standardowe
+deskryptory plików.
+Deskryptor standardowego wej¶cia zostanie pod³±czony do procesu macierzystego,
+za¶ pozosta³e dwa deskryptory plików dostan± pod³±czone do \fI/dev/null\fR.
+Funkcja \fBpw_auth\fR bêdzie potokowaæ pojedynczy wiersz danych do programu
+uwierzytelniania pos³uguj±c siê deskryptorem 0.
+.PP
+Ostatni argument stanowi dane autentykacji, u¿ywane przez
+.B PW_FTP
+oraz
+.B PW_REXEC
+Jest on traktowany jak pojedynczy wiersz tekstu potokowany do programu
+uwierzytelniaj±cego.
+Dla
+.B PW_CHANGE
+warto¶æ \fIinput\fR jest warto¶ci± poprzedniej nazwy u¿ytkownika,
+je¶li zmieniana jest nazwa.
+.SH PRZESTROGI
+Funkcja ta nie tworzy faktycznej sesji.
+Wskazuje jedynie, czy u¿ytkownik powinien otrzymaæ zezwolenie na jej
+utworzenie.
+.PP
+Obecnie opcje sieciowe nie s± jeszcze przetestowane.
+.SH DIAGNOSTYKA
+Funkcja \fBpw_auth\fR zwraca 0 je¶li program uwierzytelniania zakoñczy³
+dzia³anie z zerowym kodem powrotu, w przeciwnym wypadku warto¶æ niezerow±.
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR passwd (1),
+.BR su (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/pwauth.8 b/current/man/pl/pwauth.8
new file mode 100644
index 00000000..e87926c5
--- /dev/null
+++ b/current/man/pl/pwauth.8
@@ -0,0 +1,65 @@
+.\" {PTM/WK/1999-09-15}
+.\" Copyright 1992, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: pwauth.8,v 1.2 1999/09/25 20:07:47 wojtek2 Exp $
+.\"
+.TH PWAUTH 8
+.SH NAZWA
+pwauth \- definiowane przez administratora uwierzytelnianie hase³
+.SH OPIS
+Administrator systemu mo¿e zdefiniowaæ listê programów, jakie s± u¿ywane
+do potwierdzenia to¿samo¶ci u¿ytkownika.
+Programy te podawane s± zamiast informacji o zakodowanym ha¶le obecnej
+w pliku \fI/etc/passwd\fR albo \fI/etc/shadow\fR.
+Narzêdzia administruj±ce kontami u¿ytkowników sprawdzaj± pole zakodowanego
+has³a i stwierdzaj± czy u¿ytkownik posiada zdefiniowany przez administratora
+program uwierzytelniaj±cy (autentykuj±cy).
+Funkcja \fBpw_auth\fR zostanie wywo³ana ka¿dorazowo, gdy jeden z tych
+programów administracyjnych stwierdzi, ¿e zmieniany u¿ytkownik posiada
+zdefiniowane programy uwierzytelniania.
+.PP
+Pocz±tkowy wpis tworzony jest przez polecenie \fBuseradd\fR.
+Zmiany, takie jak zmiana informacji autentykuj±cej lub usuniêcie konta
+u¿ytkownika, spowoduj± wywo³anie funkcji \fBpw_auth\fR. Pozwala to
+na utrzymanie aktualno¶ci informacji dla ka¿dego konta.
+.PP
+Programy uwierzytelniaj±ce nie tworz± sesji pracy (loginowych) ani
+sesji sieciowych. Kod zakoñczenia programu uwierzytelniaj±cego jest
+wskazaniem czy akcja bêdzie dozwolona.
+Proces wo³aj±cy musi posiadaæ odpowiednie uprawnienia do samodzielnego
+utworzenia sesji pracy lub sesji sieciowej.
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR passwd (1),
+.BR su (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR pw_auth (3)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/pwck.8 b/current/man/pl/pwck.8
new file mode 100644
index 00000000..2b71c610
--- /dev/null
+++ b/current/man/pl/pwck.8
@@ -0,0 +1,109 @@
+.\" {PTM/WK/1999-09-14}
+.\" Copyright 1992, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: pwck.8,v 1.3 1999/09/25 20:07:47 wojtek2 Exp $
+.\"
+.TH PWCK 1
+.SH NAZWA
+pwck - weryfikacja spójno¶ci plików hase³
+.SH OPIS
+\fBpwck\fR [\fB-r\fR] [\fIpasswd\fR \fIshadow\fR]
+.SH OPIS
+\fBpwck\fR weryfikuje integralno¶æ informacji autentykacji systemowej.
+W plikach \fI/etc/passwd\fR i \fI/etc/shadow\fR sprawdzane s± wszystkie
+pozycje, by upewniæ siê, ¿e ka¿da z nich posiada w³a¶ciwy format
+i poprawne dane w ka¿dym z pól. U¿ytkownik monitowany jest o usuniêcie
+pozycji, które s± sformatowane niepoprawnie lub posiadaj± inne nie daj±ce
+siê skorygowaæ b³êdy.
+.P
+Kontrolowane jest czy ka¿da pozycja posiada
+.sp
+.in +.5i
+- w³a¶ciw± liczbê pól
+.br
+- unikaln± nazwê u¿ytkownika
+.br
+- poprawny identyfikator u¿ytkownika i grupy
+.br
+- poprawn± grupê g³ówn±
+.br
+- poprawny katalog domowy
+.br
+- poprawn± pow³okê zg³oszeniow± (startow±)
+.in -.5i
+.sp
+.P
+Kontrola w³a¶ciwej liczby pól i niepowtarzalnej nazwy u¿ytkownika jest
+decyduj±ca. Je¿eli pozycja posiada b³êdn± liczbê pól, to u¿ytkownik jest
+proszony o usuniêcie ca³ej pozycji (wiersza).
+Je¿eli u¿ytkownik nie potwierdzi decyzji o usuniêciu, to pomijane s± wszelkie
+dalsze sprawdzenia.
+Pozycja z powtórzon± nazw± u¿ytkownika powoduje monit o usuniêcie, ale nadal
+bêd± wykonywane pozosta³e sprawdzenia.
+Wszystkie inne b³êdy daj± ostrze¿enia a u¿ytkownik jest zachêcany
+do uruchomienia polecenia \fBusermod\fR, by je poprawiæ.
+.P
+Polecenia dzia³aj±ce na pliku \fI/etc/passwd\fR nie potrafi± zmieniaæ
+uszkodzonych lub powielonych pozycji. W takich okoliczno¶ciach powinien byæ
+u¿ywany \fBpwck\fR, by usun±æ nieprawid³ow± pozycjê.
+.SH OPCJE
+Domy¶lnie \fBpwck\fR dzia³a na plikach \fI/etc/passwd\fR oraz \fI/etc/shadow\fR.
+Przy pomocy parametrów \fIpasswd\fR i \fIshadow\fR u¿ytkownik mo¿e wybraæ inne
+pliki.
+Dodatkowo, u¿ytkownik mo¿e wykonaæ polecenie w trybie tylko-do-odczytu, poprzez
+podanie flagi \fB-r\fR.
+Powoduje to, ¿e na wszystkie pytania dotycz±ce zmian zostanie, bez ingerencji
+u¿ytkownika, u¿yta odpowied¼ \fBnie\fR.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - zakodowana informacja o has³ach"
+.br
+.IR /etc/group " - informacja o grupach"
+.SH ZOBACZ TAK¯E
+.BR usermod (8),
+.BR group (5),
+.BR passwd (5),
+.BR shadow (5)
+.SH DIAGNOSTYKA
+Polecenie \fBpwck\fR koñczy pracê z nastêpuj±cymi warto¶ciami kodów
+zakoñczenia:
+.IP 0 5
+Powodzenie
+.IP 1 5
+B³±d sk³adni
+.IP 2 5
+Jedna lub wiêcej z³ych pozycji pliku hase³
+.IP 3 5
+Niemo¿liwe otwarcie plików hase³
+.IP 4 5
+Niemo¿liwa blokada plików hase³
+.IP 5 5
+Niemo¿liwa aktualizacja plików hase³
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/pwconv.8 b/current/man/pl/pwconv.8
new file mode 100644
index 00000000..0916ca28
--- /dev/null
+++ b/current/man/pl/pwconv.8
@@ -0,0 +1,66 @@
+.\" {PTM/WK/1999-09-14}
+.\" $Id: pwconv.8,v 1.1 1999/09/14 18:41:35 wojtek2 Exp $
+.TH PWCONV 8 "26 wrze¶nia 1997"
+.SH NAZWA
+pwconv, pwunconv, grpconv, grpunconv - konwersja dot. chronionych plików hase³ i grup
+.SH SK£ADNIA
+.B pwconv
+.br
+.B pwunconv
+.br
+.B grpconv
+.br
+.B grpunconv
+.SH OPIS
+Wszystkie te cztery programy dzia³aj± na zwyk³ych i dodatkowych (shadow)
+plikach hase³ i grup:
+.IR /etc/passwd ", " /etc/group ", " /etc/shadow " i " /etc/gshadow .
+
+.B pwconv
+.RI "tworzy " shadow " z " passwd " i opcjonalnie istniej±cego " shadow .
+.B pwunconv
+.RI "tworzy " passwd " z " passwd " i " shadow " a nastêpnie usuwa " shadow .
+.B grpconv
+.RI "tworzy " gshadow " z " group " i opcjonalnie istniej±cego " gshadow .
+.B grpunconv
+.RI "tworzy " group " z " group " i " gshadow " a nastêpnie usuwa " gshadow .
+
+Ka¿dy z programów zdobywa niezbêdne blokady przed konwersj±.
+
+.BR pwconv " i " grpconv
+s± podobne. Po pierwsze, z pliku dodatkowego usuwane s± pozycje, które
+nie istniej± w pliku g³ównym. Nastêpnie, w pliku dodatkowym aktualizowane s±
+pozycje nie posiadaj±ce 'x' jako has³a w pliku g³ównym. Dodawane s± pozycje
+brakuj±ce w stosunku do pliku g³ównego. Na koniec, has³a w pliku g³ównym
+zastêpowane s± przez 'x'. Programy te mog± s³u¿yæ zarówno do pocz±tkowej
+konwersji jak i do aktualizacji dodatkowego pliku hase³ je¶li plik g³ówny
+zmieniany by³ rêcznie.
+
+Przy dodawaniu nowych wpisów do
+.IR /etc/shadow
+.B pwconv
+u¿yje warto¶ci
+.BR PASS_MIN_DAYS ", " PASS_MAX_DAYS " i " PASS_WARN_AGE
+z pliku
+.IR /etc/login.defs .
+
+.RB "Podobnie, " pwunconv " oraz " grpunconv
+s± zbli¿one. Has³a w pliku g³ównym aktualizowane s± na podstawie pliku
+dodatkowego (shadow). Wpisy istniej±ce w pliku g³ównym, a nie posiadaj±ce
+odpowiedników w dodatkowym s± pozostawiane bez zmian. Na koniec usuwany
+jest plik dodatkowy.
+
+Czê¶æ informacji o wa¿no¶ci hase³ jest tracona przez
+.BR pwunconv .
+Przeprowadza on konwersjê tego, co potrafi.
+.SH B£ÊDY
+B³êdy w plikach hase³ czy grup (takie jak nieprawid³owe czy powtórzone
+pozycje) mog± spowodowaæ zapêtlenie siê omawianych programów lub ró¿nego
+rodzaju inne b³êdne zachowanie. Przed konwersj± na lub z dodatkowych plików
+hase³ lub grup proszê uruchomiæ \fBpwck\fR i \fBgrpck\fR, by poprawiæ tego
+rodzaju b³êdy.
+.SH ZOBACZ TAK¯E
+.BR login.defs (5),
+.BR pwck (8),
+.BR grpck (8),
+.BR shadowconfig (8)
diff --git a/current/man/pl/shadow.3 b/current/man/pl/shadow.3
new file mode 100644
index 00000000..5ad19a23
--- /dev/null
+++ b/current/man/pl/shadow.3
@@ -0,0 +1,148 @@
+.\" {PTM/WK/1999-09-16}
+.\" Copyright 1989 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: shadow.3,v 1.2 1999/09/25 20:07:47 wojtek2 Exp $
+.\"
+.TH SHADOW 3
+.SH NAZWA
+shadow \- procedury zakodowanego pliku hase³
+.SH SK£ADNIA
+.B #include <shadow.h>
+.PP
+.B struct spwd *getspent();
+.PP
+.B struct spwd *getspnam(char
+.IB *name );
+.PP
+.B void setspent();
+.PP
+.B void endspent();
+.PP
+.B struct spwd *fgetspent(FILE
+.IB *fp );
+.PP
+.B struct spwd *sgetspent(char
+.IB *cp );
+.PP
+.B int putspent(struct spwd
+.I *p,
+.B FILE
+.IB *fp );
+.PP
+.B int lckpwdf();
+.PP
+.B int ulckpwdf();
+.SH OPIS
+.I shadow
+operuje na zawarto¶ci dodatkowego pliku hase³ (shadow) \fI/etc/shadow\fR.
+Plik \fI#include\fR opisuje strukturê
+.sp
+struct spwd {
+.in +.4i
+.br
+char *sp_namp; /* nazwa u¿ytkownika (login) */
+.br
+char *sp_pwdp; /* zakodowane has³o */
+.br
+long sp_lstchg; /* ostatnia zmiana has³a */
+.br
+int sp_min; /* dni do dozwolonej zmiany */
+.br
+int sp_max; /* dni przed wymagan± zmian± */
+.br
+int sp_warn; /* dni ostrze¿enia o wyga¶niêciu */
+.br
+int sp_inact; /* dni przed wy³±czeniem konta */
+.br
+int sp_expire; /* data wa¿no¶ci konta */
+.br
+int sp_flag; /* zarezerwowane do przysz³ego u¿ytku */
+.br
+.in -.5i
+}
+.PP
+Znaczenie poszczególnych pól:
+.sp
+sp_namp \- wska¼nik do zakoñczonej przez nul nazwy u¿ytkownika.
+.br
+sp_pwdp \- wska¼nik do zakoñczonego nul has³a.
+.br
+sp_lstchg \- dni od 1 stycznia 1970; data ostatniej zmiany has³a.
+.br
+sp_min \- dni, przed up³ywem których has³o nie mo¿e byæ zmienione.
+.br
+sp_max \- dni, po których has³o musi byæ zmienione.
+.br
+sp_warn \- dni przed dat± up³ywu wa¿no¶ci has³a, od których
+u¿ytkownik jest ostrzegany od nadchodz±cym terminie wa¿no¶ci.
+.br
+sp_inact \- dni po up³yniêciu wa¿no¶ci konta, po których konto jest
+uwa¿ane za nieaktywne i wy³±czane.
+.br
+sp_expire \- dni od 1 stycznia 1970, data gdy konto zostanie
+wy³±czone.
+.br
+sp_flag \- zarezerwowane do przysz³ego u¿ytku.
+.SH OPIS
+\fBgetspent\fR, \fBgetspname\fR, \fBfgetspent\fR i \fBsgetspent\fR
+zwracaj± wska¼nik do \fBstruct spwd\fR.
+\fBgetspent\fR zwraca nastêpn± pozycjê w pliku, za¶ \fBfgetspent\fR
+nastêpn± pozycjê z podanego strumienia. Zak³ada siê, ¿e strumieñ
+ten jest plikiem o poprawnym formacie.
+\fBsgetspent\fR zwraca wska¼nik do \fBstruct spwd\fR u¿ywaj±c jako
+wej¶cia dostarczonego ³añcucha.
+\fBgetspnam\fR wyszukuje od bie¿±cej pozycji w pliku pozycji pasuj±cej
+do \fBname\fR.
+.PP
+\fBsetspent\fR i \fBendspent\fR mog± zostaæ u¿yte do odpowiednio,
+rozpoczêcia i zakoñczenia dostêpu do chronionego pliku hase³ (shadow).
+.PP
+Do zapewnienia wy³±cznego dostêpu do pliku \fI/etc/shadow\fR powinny
+byæ u¿ywane procedury \fBlckpwdf\fR i \fBulckpwdf\fR.
+\fBlckpwdf\fR przez 15 sekund usi³uje uzyskaæ blokadê przy pomocy
+\fBpw_lock\fR.
+Kontynuuje próbê uzyskania drugiej blokady przy pomocy \fBspw_lock\fR
+przez czas pozosta³y z pocz±tkowych 15 sekund.
+Je¿eli po up³ywie 15 sekund którakolwiek z tych prób zawiedzie,
+to \fBlckpwdf\fR zwraca -1.
+Je¿eli uzyskano obie blokady, to zwracane jest 0.
+.SH DIAGNOSTYKA
+Je¿eli nie ma dalszych pozycji lub podczas przetwarzania pojawi siê b³±d,
+to procedury zwracaj± NULL.
+Procedury zwracaj±ce warto¶æ typu \fBint\fR zwracaj± 0 w przypadku powodzenia
+a -1 dla pora¿ki.
+.SH PRZESTROGI
+Procedury te mog± byæ u¿ywane wy³±cznie przez superu¿ytkownika, gdy¿ dostêp
+do dodatkowego, chronionego pliku hase³ jest ograniczony.
+.SH PLIKI
+.IR /etc/shadow " - zakodowane has³a u¿ytkowników"
+.SH ZOBACZ TAK¯E
+.BR getpwent (3),
+.BR shadow (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pl/shadow.5 b/current/man/pl/shadow.5
new file mode 100644
index 00000000..8997bead
--- /dev/null
+++ b/current/man/pl/shadow.5
@@ -0,0 +1,92 @@
+.\" 1999 PTM Przemek Borys
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: shadow.5,v 1.3 1999/09/20 20:56:42 wojtek2 Exp $
+.\"
+.TH SHADOW 5
+.SH NAZWA
+shadow \- zakodowany plik z has³ami
+.SH OPIS
+.I shadow
+zawiera zakodowane dane o has³ach dla kont u¿ytkowników oraz opcjonalne
+informacje o wieku (aging) has³a.
+Zawarte s± w nim
+.IP "" .5i
+Nazwa u¿ytkownika (nazwa logowania)
+.IP "" .5i
+Zakodowane has³o
+.IP "" .5i
+Dni, licz±c od 1 stycznia 1970, kiedy has³o by³o ostatni raz zmienione
+.IP "" .5i
+Dni przed których up³yniêciem niemo¿liwa jest zmiany has³a
+.IP "" .5i
+Dni, po których up³yniêciu konieczna jest zmiana has³a
+.IP "" .5i
+Ilo¶æ dni, jaka musi dzieliæ has³o od przedawnienia, by u¿ytkownik by³
+ostrzegany
+.IP "" .5i
+Ilo¶æ dni po przedawnieniu has³a, po których konto jest wy³±czane
+.IP "" .5i
+Dni od 1 stycznia 1970, okre¶laj±ce datê, kiedy konto jest wy³±czane
+.IP "" .5i
+Pole zarezerwowane
+.PP
+Pole has³a musi byæ wype³nione. Zakodowane has³o sk³ada siê z 13-24 znaków z
+64 znakowego alfabetu a-z, A-Z, 0-9, \. i /.
+Dla szczegó³ów interpretacji tego napisu, odsy³amy do \fIcrypt(3)\fR.
+.PP
+Data ostatniej zmiany has³a jest podawana jako liczba dni od 1 stycznia
+1970. Has³a nie mog± byæ zmieniane przed up³ywem odpowiedniej ilo¶ci dni, a
+musz± byæ zmieniane po up³ywie maksymalnej ilo¶ci dni.
+Je¶li minimalna liczba dni jest wiêksza od maksymalnej, has³o nie mo¿e byæ
+przez u¿ytkownika zmienione.
+.PP
+Je¶li has³o pozostaje niezmienione po up³ywie jego wa¿no¶ci, to konto jest
+uwa¿ane za nieaktywne i zostanie wy³±czone po ustalonej liczbie dni
+nieaktywno¶ci. Konto zostanie równie¿ wy³±czone w zadanym dniu wa¿no¶ci
+konta bez wzglêdu na informacjê o terminie wa¿no¶ci has³a.
+.PP
+Informacja w pliku \fIshadow\fR zastêpuje wszelkie has³a lub dane o ich
+wieku znajduj±ce siê w \fI/etc/passwd\fR.
+.PP
+Je¶li ma byæ utrzymywane bezpieczeñstwo hase³, to plik ten nie mo¿e byæ
+odczytywalny dla zwyk³ych u¿ytkowników.
+.SH Pliki
+.IR /etc/passwd " - informacje o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - zakodowane has³a u¿ytkowników"
+.SH ZOBACZ TAK¯E
+chage(1),
+login(1),
+passwd(1),
+su(1),
+sulogin(1M),
+shadow(3),
+passwd(5),
+pwconv(8),
+pwunconv(8)
diff --git a/current/man/pl/shadowconfig.8 b/current/man/pl/shadowconfig.8
new file mode 100644
index 00000000..2d37c1f2
--- /dev/null
+++ b/current/man/pl/shadowconfig.8
@@ -0,0 +1,27 @@
+.\" {PTM/WK/1999-09-14}
+.\" $Id: shadowconfig.8,v 1.1 1999/09/14 18:41:35 wojtek2 Exp $
+.TH SHADOWCONFIG 8 "19 kwietnia 1997" "Debian GNU/Linux"
+.SH NAZWA
+shadowconfig - prze³±cza ochronê hase³ i grup przez pliki shadow
+.SH SK£ADNIA
+.B "shadowconfig"
+.IR on " | " off
+.SH OPIS
+.PP
+.B shadowconfig on
+w³±cza ochronê hase³ i grup przez dodatkowe, przes³aniane pliki (shadow);
+.B shadowconfig off
+wy³±cza dodatkowe pliki hase³ i grup.
+.B shadowconfig
+wy¶wietla komunikat o b³êdzie i koñczy pracê z niezerowym kodem je¶li
+znajdzie co¶ nieprawid³owego. W takim wypadku powiniene¶ poprawiæ b³±d
+.\" if it finds anything awry.
+i uruchomiæ program ponownie.
+
+W³±czenie ochrony hase³, gdy jest ona ju¿ w³±czona lub jej wy³±czenie,
+gdy jest wy³±czona jest nieszkodliwe.
+
+Przeczytaj
+.IR /usr/doc/passwd/README.debian.gz ,
+gdzie znajdziesz krótkie wprowadzenie do ochrony hase³ z u¿yciem dodatkowych
+plików hase³ przes³anianych (shadow passwords) i zwi±zanych tematów.
diff --git a/current/man/pl/su.1 b/current/man/pl/su.1
new file mode 100644
index 00000000..d561e67c
--- /dev/null
+++ b/current/man/pl/su.1
@@ -0,0 +1,87 @@
+.\" {PTM/WK/1999-09-25}
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.TH SU 1
+.SH NAZWA
+su \- zmieñ ID u¿ytkownika lub stañ siê superu¿ytkownikiem
+.SH SK£ADNIA
+.BR su " [" - ]
+.RI [ nazwa_u¿ytkownika " [" argumenty ]]
+.SH OPIS
+.B su
+s³u¿y do stawania siê innym u¿ytkownikiem w trakcie w³asnej sesji pracy.
+Wywo³anie bez parametru - nazwy u¿ytkownika, domy¶lnie oznacza dla \fBsu\fR
+próbê stania siê superu¿ytkownikiem.
+Opcjonalnym argumentem \fB\-\fR mo¿na pos³u¿yæ siê do zasymulowania
+rzeczywistego rozpoczynania sesji pracy. Pozwala to na utworzenie ¶rodowiska
+u¿ytkownika. podobnego do tego, jakie wystêpuje przy bezpo¶rednim zg³oszeniu
+u¿ytkownika w systemie.
+.PP
+Po nazwie u¿ytkownika mog± wyst±piæ dodatkowe argumenty. Zostan± one
+dostarczone pow³oce zg³oszeniowej u¿ytkownika. W szczególno¶ci, argument
+\fB-c\fR spowoduje, ¿e nastêpny argument zostanie potraktowany jak polecenie
+przez wiêkszo¶æ interpretatorów poleceñ.
+.\" Polecenie zostanie wykonane przez pow³okê podan± w
+.\" \fB$SHELL\fR, albo je¶li jej nie zdefiniowano, przez podan± w
+.\" \fI/etc/passwd\fR.
+.\" XXX - powy¿sze nie by³o ca³kiem poprawne. --marekm
+Polecenie zostanie wykonane przez pow³okê wymienion± w \fI/etc/passwd\fR dla
+docelowego u¿ytkownika.
+.PP
+U¿ytkownik pytany jest o odpowiednie has³o, je¶li takowe istnieje.
+B³êdne has³a powoduj± komunikat o b³êdzie. Wszystkie próby, udane i nieudane,
+s± rejestrowane do celów wykrywania nadu¿yæ systemu.
+.PP
+Do nowej pow³oki przekazywane jest bie¿±ce ¶rodowisko.
+Warto¶æ \fB$PATH\fR dla zwyk³ych u¿ytkowników ustawiana jest jest na
+\fB/bin:/usr/bin\fR, za¶ dla superu¿ytkownika
+na \fB/sbin:/bin:/usr/sbin:/usr/bin\fR.
+Mo¿na to zmieniæ przy pomocy definicji \fBENV_PATH\fR i \fBENV_SUPATH\fR
+w \fI/etc/login.defs\fR.
+.SH PRZESTROGI
+.PP
+Niniejsza wersja \fBsu\fR posiada wiele opcji kompilacji, z których tylko
+czê¶æ bêdzie mieæ zastosowanie w danej instalacji.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - zakodowane has³a i informacja o ich wa¿no¶ci"
+.br
+.IR $HOME/.profile " - plik startowy dla domy¶lnej pow³oki"
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR sh (1),
+.BR suauth (5),
+.BR login.defs (5)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
+.SH OD T£UMACZA
+Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu
+shadow-password.
+Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz
+z w³a¶ciwej dokumentacji.
diff --git a/current/man/pl/suauth.5 b/current/man/pl/suauth.5
new file mode 100644
index 00000000..c3a54ac7
--- /dev/null
+++ b/current/man/pl/suauth.5
@@ -0,0 +1,115 @@
+.\" {PTM/WK/1999-09-14}
+.TH SUAUTH 5 "14 lutego 1996"
+.UC 5
+.SH NAZWA
+suauth - plik szczegó³owej kontroli su
+.\" detailed su control file
+.SH SK£ADNIA
+.B /etc/suauth
+.SH OPIS
+Plik
+.I /etc/suauth
+przeszukiwany jest przy ka¿dym wywo³aniu polecenia su. Mo¿e on zmieniaæ
+zachowanie siê polecenia su, w oparciu o
+.PP
+.RS
+.nf
+1) u¿ytkownika, na którego konto wykonywane jest su
+.fi
+2) u¿ytkownika wykonuj±cego polecenie su (lub dowoln± z grup, której mo¿e
+on byæ cz³onkiem)
+.RE
+.PP
+Plik sformatowany jest jak poni¿ej. Wiersze rozpoczynaj±ce siê od # s±
+traktowane jak wiersze komentarza i ignorowane.
+.PP
+.RS
+na-ID:z-ID:AKCJA
+.RE
+.PP
+Gdzie na-ID jest albo s³owem
+.B ALL
+(wszyscy), albo list± nazw u¿ytkowników rozdzielonych "," albo te¿ s³owami
+.B ALL EXCEPT
+(wszyscy oprócz), po których nastêpuje lista nazw u¿ytkowników
+rozdzielonych przecinkiem.
+.PP
+z-ID jest formatowane w taki sam sposób jak na-ID, z wyj±tkiem tego, ¿e
+rozpoznawane jest dodatkowe s³owo
+.BR GROUP.
+Zapis
+.B ALL EXCEPT GROUP
+(wszyscy za wyj±tkiem grupy) jest równie¿ ca³kowicie poprawny.
+Po s³owie
+.B GROUP
+powinna wyst±piæ jedna lub wiêcej rozdzielonych przecinkiem nazw grup.
+Niewystarczaj±ce jest podanie g³ównego ID danej grupy - niezbêdny jest
+wpis w
+.BR /etc/group (5).
+.PP
+Akcja mo¿e byæ tylko jedn± z obecnie obs³ugiwanych opcji:
+.TP 10
+.B DENY
+(zakaz) Próba wykonania su jest zatrzymywana jeszcze przed pytaniem o has³o.
+.TP 10
+.B NOPASS
+(bez has³a) Próba wykonania su jest automatycznie pomy¶lna; brak pytania
+o has³o.
+.TP 10
+.B OWNPASS
+(w³asne has³o) U¿ytkownik wywo³uj±cy su musi wprowadziæ w³asne has³o, by
+polecenie zosta³o pomy¶lnie wykonane. Jest on powiadamiany o konieczno¶ci
+podania w³asnego has³a.
+.PP
+Zauwa¿, ¿e istniej± trzy odrêbne pola rozdzielone dwukropkiem. Bia³e znaki
+wokó³ dwukropka nie s± dozwolone. Zauwa¿ te¿, ¿e plik analizowany jest
+sekwencyjnie, wiersz po wierszu, i stosowana jest pierwsza pasuj±ca regu³a
+bez analizy reszty pliku. Umo¿liwia to administratorowi systemu precyzyjn±
+kontrolê wed³ug w³asnych upodobañ.
+.SH PRZYK£AD
+.PP
+.nf
+# przyk³adowy plik /etc/suauth
+#
+# para uprzywilejowanych u¿ytkowników
+# mo¿e wykonaæ su na konto root
+# przy pomocy w³asnych hase³
+#
+root:chris,birddog:OWNPASS
+#
+# Nikt inny nie mo¿e wykonaæ su na konto root,
+# chyba ¿e jest cz³onkiem grupy wheel.
+# Tak to robi BSD.
+#
+root:ALL EXCEPT GROUP wheel:DENY
+#
+# Byæ mo¿e terry i birddog s± kontami,
+# których u¿ywa ta sama osoba.
+# Mo¿na zrobiæ wzajemny dostêp
+# pomiêdzy nimi bez hase³.
+#
+terry:birddog:NOPASS
+birddog:terry:NOPASS
+#
+.fi
+.SH PLIKI
+.I /etc/suauth
+.SH B£ÊDY
+Mo¿e byæ sporo ukrytych. Analizator pliku jest szczególnie wra¿liwy
+na b³êdy sk³adniowe. Zak³ada on, ¿e nie bêdzie zbêdnych bia³ych znaków
+(za wyj±tkiem pocz±tków i koñców wierszy), a ró¿ne elementy bêd± separowane
+konkretnym znakiem ogranicznika.
+.SH DIAGNOSTYKA
+B³±d analizy pliku zg³aszany jest przy u¿yciu
+.BR syslogd (8)
+jako zagro¿enie o poziomie ERR (b³±d) w podsystemie AUTH (identyfikacji
+u¿ytkownika przy zg³oszeniu).
+.\" as level ERR on facility AUTH.
+.SH ZOBACZ TAK¯E
+.BR su (1)
+.SH AUTOR
+.nf
+Chris Evans (lady0110@sable.ox.ac.uk)
+Lady Margaret Hall
+Oxford University
+England
diff --git a/current/man/pl/sulogin.8 b/current/man/pl/sulogin.8
new file mode 100644
index 00000000..e8aca99d
--- /dev/null
+++ b/current/man/pl/sulogin.8
@@ -0,0 +1,94 @@
+.\" {PTM/WK/1999-09-14}
+.\" Copyright 1989 - 1992, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: sulogin.8,v 1.3 1999/09/25 20:07:47 wojtek2 Exp $
+.\"
+.TH SULOGIN 8
+.SH NAZWA
+sulogin - login w trybie jednou¿ytkownikowym
+.SH SK£ADNIA
+\fBsulogin\fR [\fIurz±dzenie-tty\fR]
+.SH OPIS
+.B sulogin
+wywo³ywane jest przez \fBinit\fR przed zezwoleniem u¿ytkownikowi
+na dostêp do systemu w trybie jednou¿ytkownikowym (single user mode).
+Funkcja ta mo¿e byæ dostêpna tylko w niektórych systemach, w których
+odpowiednio zmieniono \fBinit\fR lub plik \fB/etc/inittab\fR posiada
+pozycjê dla logowania siê w trybie jednou¿ytkownikowym.
+.PP
+Wy¶wietlany jest symbol zachêty
+.IP "" .5i
+Type control-d to proceed with normal startup,
+.br
+(or give root password for system maintenance):
+.br
+Naci¶nij control-d by kontynuowaæ zwyk³y start,
+.br
+(lub podaj has³o u¿ytkownika root do konserwacji systemu):
+.PP
+Wej¶cie i wyj¶cie bêd± obs³ugiwane przy u¿yciu standardowych deskryptorów
+plików, chyba ¿e u¿yto opcjonalnego argumentu - nazwy urz±dzenia.
+.PP
+Je¶li u¿ytkownik wprowadzi poprawne has³o superu¿ytkownika root,
+to rozpoczynana jest sesja pracy na koncie root.
+Je¿eli natomiast naci¶niêto \fBEOF\fR, to system przechodzi
+do wielou¿ytkownikowego trybu pracy.
+.PP
+Po opuszczeniu przez u¿ytkownika pow³oki przypisanej do
+jednou¿ytkownikowego trybu pracy lub po naci¶niêciu \fBEOF\fR, system
+wykonuje proces inicjacji wymagany do przej¶cia w tryb wielou¿ytkownikowy.
+.SH OSTRZE¯ENIA
+.PP
+Polecenie to mo¿e byæ u¿ywane wy³±cznie wtedy, gdy \fBinit\fR zosta³ zmieniony
+tak, by wywo³ywaæ \fBsulogin\fR zamiast \fB/bin/sh\fR,
+albo gdy u¿ytkownik skonfigurowa³ plik \fIinittab\fR tak, by obs³ugiwa³
+logowanie w trybie jednou¿ytkownikowym.
+Na przyk³ad, wiersz
+.br
+.sp 1
+co:s:respawn:/etc/sulogin /dev/console
+.br
+.sp 1
+powinien wykonaæ polecenie sulogin w trybie jednou¿ytkownikowym.
+.PP
+Na ile jest to mo¿liwe, tworzone jest pe³ne ¶rodowisko.
+Jednak¿e w efekcie mog± nie byæ do³±czone czy zainicjowane ró¿ne
+urz±dzenia, za¶ wiele poleceñ u¿ytkownika mo¿e byæ niedostêpnych lub
+nie funkcjonowaæ.
+.SH PLIKI
+.IR /etc/passwd " - informacja o kontach u¿ytkowników"
+.br
+.IR /etc/shadow " - zakodowane has³a i informacja o ich wa¿no¶ci"
+.br
+.IR /.profile " - skrypt startowy dla pow³oki trybu jednou¿ytkownikowego"
+.SH ZOBACZ TAK¯E
+.BR login (1),
+.BR init (8),
+.BR sh (1)
+.SH AUTOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/porttime.5 b/current/man/porttime.5
new file mode 100644
index 00000000..82f0ebfd
--- /dev/null
+++ b/current/man/porttime.5
@@ -0,0 +1,84 @@
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: porttime.5,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH PORTTIME 5
+.SH NAME
+porttime \- port access time file
+.SH DESCRIPTION
+.I porttime
+contains a list of tty devices, user names, and permitted login times.
+.PP
+Each entry consists of three colon separated fields.
+The first field is a comma separated list of tty devices,
+or an asterisk to indicate that all tty devices are matched by this entry.
+The second field is a comma separated list of user names, or an
+asterisk to indicated that all user names are matched by this entry.
+The third field is a comma separated list of permitted access times.
+.PP
+Each access time entry consists of zero or more days of the week,
+abbreviated \fBSu\fR, \fBMo\fR, \fBTu\fR, \fBWe\fR, \fBTh\fR,
+\fBFr\fR, and \fBSa\fR, followed by a pair of times separated by
+a hyphen.
+The abbreviation \fBWk\fR may be used to represent Monday thru Friday,
+and \fBAl\fR may be used to indicate every day.
+If no days are given, \fBAl\fR is assumed.
+.SH EXAMPLES
+The following entry allows access to user \fBjfh\fR on every port
+during weekdays from 9am to 5pm.
+.br
+.sp 1
+ *:jfh:Wk0900-1700
+.br
+.sp 1
+The following entries allow access only to the users \fBroot\fR and
+\fBoper\fR on /dev/console at any time.
+This illustrates how the
+\fI/etc/porttime\fR file is an ordered list of access times.
+Any other user would match the second entry which does not permit
+access at any time.
+.br
+.sp 1
+ console:root,oper:Al0000-2400
+.br
+ console:*:
+.br
+.sp 1
+The following entry allows access for the user \fBgames\fR on any
+port during non-working hours.
+.br
+.sp 1
+ *:games:Wk1700-0900,SaSu0000-2400
+.br
+.sp 1
+.SH FILES
+/etc/porttime \- file containing port access times
+.SH SEE ALSO
+.BR login (1)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pw_auth.3 b/current/man/pw_auth.3
new file mode 100644
index 00000000..b3e6d1c0
--- /dev/null
+++ b/current/man/pw_auth.3
@@ -0,0 +1,159 @@
+.\" Copyright 1992 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: pw_auth.3,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH PWAUTH 3
+.SH NAME
+pwauth \- administrator defined password authentication routines
+.SH SYNTAX
+.B #include <pwauth.h>
+.PP
+.B int pw_auth (char
+.I *command,
+.B char
+.I *user,
+.B int
+.I reason,
+.B char
+.IB *input) ;
+.SH DESCRIPTION
+.B pw_auth
+invokes the administrator defined functions for a given user.
+.PP
+\fIcommand\fR is the name of the authentication program.
+It is retrieved from the user's password file information.
+The string contains one or more executable file names, delimited by
+semi-colons.
+Each program will be executed in the order given.
+The command line arguments are given for each of the reasons listed
+below.
+.PP
+\fIuser\fR is the name of the user to be authenticated, as given
+in the \fI/etc/passwd\fR file.
+User entries are indexed by username.
+This allows non-unique user IDs to be present and for each different
+username associated with that user ID to have a different
+authentication program and information.
+.PP
+Each of the permissible authentication reasons is handled in a
+potentially differenent manner.
+Unless otherwise mentioned, the standard file descriptors 0, 1, and
+2 are available for communicating with the user.
+The real user ID may be used to determine the identity of the user
+making the authentication request.
+\fIreason\fR is one of
+.IP \fBPW_SU\fR 1i
+Perform authentication for the current real user ID attempting to
+switch real user ID to the named user.
+The authentication program will be invoked with a \fB-s\fR option, followed
+by the username.
+.IP \fBPW_LOGIN\fR 1i
+Perform authentication for the named user creating a new login session.
+The authentication program will be invoked with a \fB-l\fR option, followed
+by the username.
+.IP \fBPW_ADD\fR 1i
+Create a new entry for the named user.
+This allows an authentication program to initialize storage for a new
+user.
+The authentication program will be invoked with a \fB-a\fR option, followed
+by the username.
+.IP \fBPW_CHANGE\fR 1i
+Alter an existing entry for the named user.
+This allows an authentication program to alter the authentication
+information for an existing user.
+The authentication program will be invoked with a \fB-c\fR option, followed
+by the username.
+.IP \fBPW_DELETE\fR 1i
+Delete authentication information for the named user.
+This allows an authentication program to reclaim storage for a user which
+is no longer authenticated using the authentication program.
+The authentication program will be invoked with a \fB-d\fR option, followed
+by the username.
+.IP \fBPW_TELNET\fR 1i
+Authenticate a user who is connecting to the system using the
+fBtelnet\fR command.
+The authentication program will be invoked with a \fB-t\fR option, followed
+by the username.
+.IP \fBPW_RLOGIN\fR 1i
+Authenticate a user who is connecting to the system using the \fBrlogin\fR
+command.
+The authentication program will be invoked with a \fB-r\fR option, followed
+by the username.
+.IP \fBPW_FTP\fR 1i
+Authenticate a user who is connecting to the system using the \fBftp\fR
+command.
+The authentication program will be invoked with a \fR-f\fR option, followed
+by the username.
+The standard file descriptors are not available for communicating with the
+user.
+The standard input file descriptor will be connected to the parent process,
+while the other two output file descriptors will be connected to
+\fI/dev/null\fR.
+The \fBpw_auth\fR function will pipe a single line of data to the
+authentication program using file descriptor 0.
+.IP \fBPW_REXEC\fR 1i
+Authenticate a user who is connecting to the system using the \fIrexec\fR
+command.
+The authentication program will be invoked with a \fB-x\fR option, followed
+by the username.
+The standard file descriptors are not available for communicating with the
+remote user.
+The standard input file descriptor will be connected to the parent process,
+while the other two output file descriptors will be connected to
+\fI/dev/null\fR.
+The \fBpw_auth\fR function will pipe a single line of data to the
+authentication program using file descriptor 0.
+.PP
+The last argument is the authentication data which is used by the
+.B PW_FTP
+and
+.B PW_REXEC
+reasons.
+It is treated as a single line of text which is piped to the authentication
+program.
+When the reason is
+.BR PW_CHANGE,
+the value of \fIinput\fR is the value of
+previous user name if the user name is being changed.
+.SH CAVEATS
+This function does not create the actual session.
+It only indicates if the user should be allowed to create the session.
+.PP
+The network options are untested at this time.
+.SH DIAGNOSTICS
+The \fBpw_auth\fR function returns 0 if the authentication program exited
+with a 0 exit code, and a non-zero value otherwise.
+.SH SEE ALSO
+.BR login (1),
+.BR passwd (1),
+.BR su (1),
+.BR useradd (8),
+.BR userdel (8),
+usermod(8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pwauth.8 b/current/man/pwauth.8
new file mode 100644
index 00000000..156ec533
--- /dev/null
+++ b/current/man/pwauth.8
@@ -0,0 +1,67 @@
+.\" Copyright 1992, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: pwauth.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH PWAUTH 8
+.SH NAME
+pwauth \- administrator defined password authentication
+.SH DESCRIPTION
+The system administrator is able to define a list of programs which
+are used to validate a user's identity.
+These programs are given in place of the encrypted password
+information which is present in either the \fI/etc/passwd\fR or
+\fI/etc/shadow\fR files.
+The utilities which administer user accounts examine the encrypted
+password field and determine if the user has an administrator defined
+authentication program.
+The \fBpw_auth\fR function will be invoked whenever one of these
+administration programs determines that a user which is being altered
+has authentication programs defined.
+.PP
+The initial entry is created with the \fBuseradd\fR command.
+Alterations, such as changing authentication information or deleting
+the user account, will cause the \fBpw_auth\fR function to be invoked.
+This keeps the authentication information up to date for each user
+account.
+.PP
+The authentication programs do not create the actual login or network
+sessions.
+The exit code from the authentication program is taken as an
+indication that the action is to be permitted.
+The calling process must have the appropriate priviledges to create
+the login or network session itself.
+.SH SEE ALSO
+.BR login (1),
+.BR passwd (1),
+.BR su (1),
+.BR useradd (8),
+.BR userdel (8),
+.BR usermod (8),
+.BR pw_auth (3)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pwck.8 b/current/man/pwck.8
new file mode 100644
index 00000000..6e500fcb
--- /dev/null
+++ b/current/man/pwck.8
@@ -0,0 +1,107 @@
+.\" Copyright 1992, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: pwck.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH PWCK 1
+.SH NAME
+pwck \- verify integrity of password files
+.SH SYNOPSIS
+\fBpwck\fR [\fB-r\fR] [\fIpasswd\fR \fIshadow\fR]
+.SH DESCRIPTION
+\fBpwck\fR verifies the integrity of the system authentication information.
+All entries in the \fI/etc/passwd\fR and \fI/etc/shadow\fR are checked to
+see that the entry has the proper format and valid data in each field.
+The user is prompted to delete entries that are improperly formatted or
+which have other incorrectable errors.
+.P
+Checks are made to verify that each entry has
+.sp
+.in +.5i
+- the correct number of fields
+.br
+- a unique user name
+.br
+- a valid user and group identifier
+.br
+- a valid primary group
+.br
+- a valid home directory
+.br
+- a valid login shell
+.in -.5i
+.sp
+.P
+The checks for correct number of fields and unique user name are fatal.
+If the entry has the wrong number of fields, the user will be prompted to
+delete the entire line.
+If the user does not answer affirmatively, all further checks are bypassed.
+An entry with a duplicated user name is prompted for deletion, but the
+remaining checks will still be made.
+All other errors are warning and the user is encouraged to run the
+\fBusermod\fR command to correct the error.
+.P
+The commands which operate on the \fI/etc/passwd\fR file are not able to
+alter corrupted or duplicated entries.
+\fBpwck\fR should be used in those circumstances to remove the offending
+entry.
+.SH OPTIONS
+By default, \fBpwck\fR operates on the files \fI/etc/passwd\fR and
+\fI/etc/shadow\fR.
+The user may select alternate files with the \fIpasswd\fR and \fIshadow\fR
+parameters.
+Additionally, the user may execute the command in read-only mode by
+specifying the \fB-r\fR flag.
+This causes all questions regarding changes to be answered \fBno\fR
+without user intervention.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- encrypted password information
+.br
+/etc/group \- group information
+.SH SEE ALSO
+.BR usermod (8),
+.BR group (5),
+.BR passwd (5),
+.BR shadow (5)
+.SH DIAGNOSTICS
+The \fBpwck\fR command exits with the following values:
+.IP 0 5
+Success
+.IP 1 5
+Syntax Error
+.IP 2 5
+One or more bad password entries
+.IP 3 5
+Cannot open password files
+.IP 4 5
+Cannot lock password files
+.IP 5 5
+Cannot update password files
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/pwconv.8 b/current/man/pwconv.8
new file mode 100644
index 00000000..f7bafba5
--- /dev/null
+++ b/current/man/pwconv.8
@@ -0,0 +1,63 @@
+.\" $Id: pwconv.8,v 1.8 1998/06/25 22:10:43 marekm Exp $
+.TH PWCONV 8 "26 Sep 1997"
+.SH NAME
+pwconv, pwunconv, grpconv, grpunconv \- convert to and from shadow passwords and groups.
+.SH SYNOPSIS
+.B pwconv
+.br
+.B pwunconv
+.br
+.B grpconv
+.br
+.B grpunconv
+.SH DESCRIPTION
+These four programs all operate on the normal and shadow password and
+group files:
+.IR /etc/passwd ", " /etc/group ", " /etc/shadow ", and " /etc/gshadow .
+
+.B pwconv
+.RI "creates " shadow " from " passwd " and an optionally existing " shadow .
+.B pwunconv
+.RI "creates " passwd " from " passwd " and " shadow " and then removes " shadow .
+.B grpconv
+.RI "creates " gshadow " from " group " and an optionally existing " gshadow .
+.B grpunconv
+.RI "creates " group " from " group " and " gshadow " and then removes " gshadow .
+
+Each program acquires the necessary locks before conversion.
+
+.BR pwconv " and " grpconv
+are similiar. First, entries in the shadowed file which don't exist
+in the main file are removed. Then, shadowed entries which don't have
+`x' as the password in the main file are updated. Any missing
+shadowed entries are added. Finally, passwords in the main file are
+replaced with `x'. These programs can be used for initial conversion
+as well to update the shadowed file if the main file is edited by
+hand.
+
+.B pwconv
+will use the values of
+.BR PASS_MIN_DAYS ", " PASS_MAX_DAYS ", and " PASS_WARN_AGE
+from
+.I /etc/login.defs
+when adding new entries to
+.IR /etc/shadow .
+
+.RB "Likewise, " pwunconv " and " grpunconv
+are similiar. Passwords in the main file are updated from the
+shadowed file. Entries which exist in the main file but not in the
+shadowed file are left alone. Finally, the shadowed file is removed.
+
+Some password aging information is lost by
+.BR pwunconv .
+It will convert what it can.
+.SH "BUGS"
+Errors in the password or group files (such as invalid or duplicate
+entries) may cause these programs to loop forever or fail in other
+strange ways. Please run \fBpwck\fR and \fBgrpck\fR to correct any
+such errors before converting to or from shadow passwords or groups.
+.SH "SEE ALSO"
+.BR login.defs (5),
+.BR pwck (8),
+.BR grpck (8),
+.BR shadowconfig (8)
diff --git a/current/man/shadow.3 b/current/man/shadow.3
new file mode 100644
index 00000000..0a3b74a9
--- /dev/null
+++ b/current/man/shadow.3
@@ -0,0 +1,148 @@
+.\" Copyright 1989 - 1993, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: shadow.3,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH SHADOW 3
+.SH NAME
+shadow \- encrypted password file routines
+.SH SYNTAX
+.B #include <shadow.h>
+.PP
+.B struct spwd *getspent();
+.PP
+.B struct spwd *getspnam(char
+.IB *name );
+.PP
+.B void setspent();
+.PP
+.B void endspent();
+.PP
+.B struct spwd *fgetspent(FILE
+.IB *fp );
+.PP
+.B struct spwd *sgetspent(char
+.IB *cp );
+.PP
+.B int putspent(struct spwd
+.I *p,
+.B FILE
+.IB *fp );
+.PP
+.B int lckpwdf();
+.PP
+.B int ulckpwdf();
+.SH DESCRIPTION
+.I shadow
+manipulates the contents of the shadow password file,
+\fI/etc/shadow\fR.
+The structure in the \fI#include\fR file is
+.sp
+struct spwd {
+.in +.5i
+.br
+ char *sp_namp; /* user login name */
+.br
+ char *sp_pwdp; /* encrypted password */
+.br
+ long sp_lstchg; /* last password change */
+.br
+ int sp_min; /* days until change allowed. */
+.br
+ int sp_max; /* days before change required */
+.br
+ int sp_warn; /* days warning for expiration */
+.br
+ int sp_inact; /* days before account inactive */
+.br
+ int sp_expire; /* date when account expires */
+.br
+ int sp_flag; /* reserved for future use */
+.br
+.in -.5i
+}
+.PP
+The meanings of each field are
+.sp
+sp_namp \- pointer to null-terminated user name.
+.br
+sp_pwdp \- pointer to null-terminated password.
+.br
+sp_lstchg \- days since Jan 1, 1970 password was last changed.
+.br
+sp_min \- days before which password may not be changed.
+.br
+sp_max \- days after which password must be changed.
+.br
+sp_warn \- days before password is to expire that user is warned
+of pending password expiration.
+.br
+sp_inact \- days after password expires that account is considered
+inactive and disabled.
+.br
+sp_expire \- days since Jan 1, 1970 when account will be disabled.
+.br
+sp_flag \- reserved for future use.
+.SH DESCRIPTION
+\fBgetspent\fR, \fBgetspname\fR, \fBfgetspent\fR, and \fBsgetspent\fR
+each return a pointer to a \fBstruct spwd\fR.
+\fBgetspent\fR returns the
+next entry from the file, and \fBfgetspent\fR returns the next
+entry from the given stream, which is assumed to be a file of
+the proper format.
+\fBsgetspent\fR returns a pointer to a \fBstruct spwd\fR using the
+provided string as input.
+\fBgetspnam\fR searches from the current position in the file for
+an entry matching \fBname\fR.
+.PP
+\fBsetspent\fR and \fBendspent\fR may be used to begin and end,
+respectively, access to the shadow password file.
+.PP
+The \fBlckpwdf\fR and \fBulckpwdf\fR routines should be used to
+insure exclusive access to the \fI/etc/shadow\fR file.
+\fBlckpwdf\fR attempts to acquire a lock using \fBpw_lock\fR for
+up to 15 seconds.
+It continues by attempting to acquire a second lock using \fBspw_lock\fR
+for the remainder of the initial 15 seconds.
+Should either attempt fail after a total of 15 seconds, \fBlckpwdf\fR
+returns -1.
+When both locks are acquired 0 is returned.
+.SH DIAGNOSTICS
+Routines return NULL if no more entries are available or if an
+error occurs during processing.
+Routines which have \fBint\fR as the return value return 0 for
+success and -1 for failure.
+.SH CAVEATS
+These routines may only be used by the super user as access to
+the shadow password file is restricted.
+.SH FILES
+/etc/shadow \- encrypted user passwords
+.SH SEE ALSO
+.BR getpwent (3),
+.BR shadow (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/shadow.5 b/current/man/shadow.5
new file mode 100644
index 00000000..bd3b09a3
--- /dev/null
+++ b/current/man/shadow.5
@@ -0,0 +1,99 @@
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: shadow.5,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH SHADOW 5
+.SH NAME
+shadow \- encrypted password file
+.SH DESCRIPTION
+.I shadow
+contains the encrypted password information for user's accounts
+and optional the password aging information.
+Included is
+.IP "" .5i
+Login name
+.IP "" .5i
+Encrypted password
+.IP "" .5i
+Days since Jan 1, 1970 that password was last changed
+.IP "" .5i
+Days before password may be changed
+.IP "" .5i
+Days after which password must be changed
+.IP "" .5i
+Days before password is to expire that user is warned
+.IP "" .5i
+Days after password expires that account is disabled
+.IP "" .5i
+Days since Jan 1, 1970 that account is disabled
+.IP "" .5i
+A reserved field
+.PP
+The password field must be filled.
+The encryped password consists of 13 to 24 characters from the
+64 character alphabet
+a thru z, A thru Z, 0 thru 9, \. and /.
+Refer to \fBcrypt\fR(3) for details on how this string is
+interpreted.
+.PP
+The date of the last password change is given as the number
+of days since Jan 1, 1970.
+The password may not be changed again until the proper number
+of days have passed, and must be changed after the maximum
+number of days.
+If the minimum number of days required is greater than the
+maximum number of day allowed, this password may not be
+changed by the user.
+.PP
+An account is considered to be inactive and is disabled if
+the password is not changed within the specified number of
+days after the password expires.
+An account will also be disabled on the specified day
+regardless of other password expiration information.
+.PP
+This information supercedes any password or password age
+information present in \fI/etc/passwd\fR.
+.PP
+This file must not be readable by regular users if password
+security is to be maintained.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- encrypted user passwords
+.SH SEE ALSO
+.BR chage (1),
+.BR login (1),
+.BR passwd (1),
+.BR su (1),
+.BR sulogin (8),
+.BR shadow (3),
+.BR passwd (5),
+.BR pwconv (8),
+.BR pwunconv (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/shadowconfig.8 b/current/man/shadowconfig.8
new file mode 100644
index 00000000..ac6af945
--- /dev/null
+++ b/current/man/shadowconfig.8
@@ -0,0 +1,24 @@
+.\" $Id: shadowconfig.8,v 1.2 1997/12/14 20:07:22 marekm Exp $
+.TH SHADOWCONFIG 8 "19 Apr 1997" "Debian GNU/Linux"
+.SH NAME
+shadowconfig \- toggle shadow passwords on and off
+.SH SYNOPSIS
+.B "shadowconfig"
+.IR on " | " off
+.SH DESCRIPTION
+.PP
+.B shadowconfig on
+will turn shadow passwords on;
+.B shadowconfig off
+will turn shadow passwords off.
+.B shadowconfig
+will print an error message and exit with a nonzero code if it finds
+anything awry. If that happens, you should correct the error and run
+it again.
+
+Turning shadow passwords on when they are already on, or off when they
+are already off, is harmless.
+
+Read
+.I /usr/doc/passwd/README.debian.gz
+for a brief introduction to shadow passwords and related features.
diff --git a/current/man/su.1 b/current/man/su.1
new file mode 100644
index 00000000..69fe12c4
--- /dev/null
+++ b/current/man/su.1
@@ -0,0 +1,87 @@
+.\" Copyright 1989 - 1990, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: su.1,v 1.6 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH SU 1
+.SH NAME
+su \- Change user ID or become super-user
+.SH SYNOPSIS
+.BR su " [" - ]
+.RI [ username " [" args ]]
+.SH DESCRIPTION
+.B su
+is used to become another user during a login session.
+Invoked without a username, \fBsu\fR defaults to becoming
+the super user.
+The optional argument \fB\-\fR may be used to provide an
+environment similiar to what the user would expect had
+the user logged in directly.
+.PP
+Additional arguments may be provided after the username,
+in which case they are supplied to the user\'s login shell.
+In particular, an argument of \fB-c\fR will cause the
+next argument to be treated as a command by most command
+interpreters.
+.\" The command will be executed under the shell specified by
+.\" \fB$SHELL\fR, or if undefined, by the one specified in
+.\" \fI/etc/passwd\fR.
+.\" XXX - the above was not quite correct. --marekm
+The command will be executed by the shell specified in
+\fI/etc/passwd\fR for the target user.
+.PP
+The user will be prompted for a password, if appropriate.
+Invalid passwords will produce an error message.
+All attempts, both valid and invalid, are logged to detect
+abuses of the system.
+.PP
+The current environment is passed to the new shell. The value of
+\fB$PATH\fR is reset to \fB/bin:/usr/bin\fR for normal users, or
+\fB/sbin:/bin:/usr/sbin:/usr/bin\fR for the super user. This may be
+changed with the \fBENV_PATH\fR and \fBENV_SUPATH\fR definitions in
+\fI/etc/login.defs\fR.
+.PP
+A subsystem login is indicated by the presense of a "*" as the first
+character of the login shell. The given home directory will be used as
+the root of a new filesystem which the user is actually logged into.
+.SH CAVEATS
+.PP
+This version of \fBsu\fR has many compilation options, only some of which
+may be in use at any particular site.
+.SH Files
+/etc/passwd \- user account information
+.br
+/etc/shadow \- encrypted passwords and age information
+.br
+$HOME/.profile \- initialization script for default shell
+.SH SEE ALSO
+.BR login (1),
+.BR sh (1),
+.BR suauth (5),
+.BR login.defs (5)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/suauth.5 b/current/man/suauth.5
new file mode 100644
index 00000000..a3aa1581
--- /dev/null
+++ b/current/man/suauth.5
@@ -0,0 +1,112 @@
+.TH SUAUTH 5 "Feb 14, 1996"
+.UC 5
+.SH NAME
+suauth \- Detailed su control file
+.SH SYNOPSIS
+.B /etc/suauth
+.SH DESCRIPTION
+The file
+.I /etc/suauth
+is referenced whenever the su command is called. It can change the
+behaviour of the su command, based upon
+.PP
+.RS
+.nf
+1) the user su is targetting
+.fi
+2) the user executing the su command (or any groups he might be
+a member of)
+.RE
+.PP
+The file is formatted like this, with lines starting with a #
+being treated as comment lines and ignored;
+.PP
+.RS
+to-id:from-id:ACTION
+.RE
+.PP
+Where to-id is either the word
+.BR ALL ,
+a list of usernames
+delimited by "," or the words
+.B ALL EXCEPT
+followed by a list
+of usernames delimted by ","
+.PP
+from-id is formatted the same as to-id except the extra word
+.B GROUP
+is recognised.
+.B ALL EXCEPT GROUP
+is perfectly valid too.
+Following
+.B GROUP
+appears one or more group names, delimited by
+",". It is not sufficient to have primary group id of the
+relevant group, an entry in
+.BR /etc/group (5)
+is neccessary.
+.PP
+Action can be one only of the following currently supported
+options.
+.TP 20
+.B DENY
+The attempt to su is stopped before a password is even asked for.
+.TP 20
+.B NOPASS
+The attempt to su is automatically successful; no password is
+asked for.
+.TP 20
+.B OWNPASS
+For the su command to be successful, the user must enter
+his or her own password. They are told this.
+.PP
+Note there are three separate fields delimted by a colon. No
+whitespace must surround this colon. Also note that the file
+is examined sequentially line by line, and the first applicable
+rule is used without examining the file further. This makes it
+possible for a system administrator to exercise as fine control
+as he or she wishes.
+.SH EXAMPLE
+.PP
+.nf
+# sample /etc/suauth file
+#
+# A couple of privileged usernames may
+# su to root with their own password.
+#
+root:chris,birddog:OWNPASS
+#
+# Anyone else may not su to root unless in
+# group wheel. This is how BSD does things.
+#
+root:ALL EXCEPT GROUP wheel:DENY
+#
+# Perhaps terry and birddog are accounts
+# owned by the same person.
+# Access can be arranged between them
+# with no password.
+#
+terry:birddog:NOPASS
+birddog:terry:NOPASS
+#
+.fi
+.SH FILES
+/etc/suauth
+.SH BUGS
+There could be plenty lurking. The file parser is particularly
+unforgiving about syntax errors, expecting no spurious whitespace
+(apart from beginning and end of lines), and a specific token
+delimiting different things.
+.SH DIAGNOSTICS
+An error parsing the file is reported using
+.BR syslogd (8)
+as level ERR on
+facility AUTH.
+.SH SEE ALSO
+.BR su (1)
+.SH AUTHOR
+.nf
+Chris Evans (lady0110@sable.ox.ac.uk)
+Lady Margaret Hall
+Oxford University
+England
diff --git a/current/man/sulogin.8 b/current/man/sulogin.8
new file mode 100644
index 00000000..61d61cdb
--- /dev/null
+++ b/current/man/sulogin.8
@@ -0,0 +1,88 @@
+.\" Copyright 1989 - 1992, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: sulogin.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH SULOGIN 8
+.SH NAME
+sulogin \- Single-user login
+.SH SYNTAX
+\fBsulogin\fR [\fItty-device\fR]
+.SH DESCRIPTION
+.B sulogin
+is invoked by \fBinit\fR prior to allowing the user
+access to the system when in single user mode.
+This feature may only be available on certain systems where
+\fBinit\fR has been modified accordingly, or where the
+\fB/etc/inittab\fR has an entry for a single user login.
+.PP
+The user is prompted
+.IP "" .5i
+Type control-d to proceed with normal startup,
+.br
+(or give root password for system maintenance):
+.PP
+Input and output will be performed with the standard file
+descriptors unless the optional device name argument is provided.
+.PP
+If the user enters the correct root password, a login session
+is initiated.
+When \fBEOF\fR is pressed instead, the system enters multi-user
+mode.
+.PP
+After the user exits the single-user shell, or presses \fBEOF\fR,
+the system begins the initialization process required to enter
+multi-user mode.
+.SH CAVEATS
+.PP
+This command can only be used if \fBinit\fR has been modified to call
+\fBsulogin\fR instead of \fB/bin/sh\fR,
+or if the user has set the \fIinittab\fR to support a single user
+login.
+For example, the line
+.br
+.sp 1
+co:s:respawn:/etc/sulogin /dev/console
+.br
+.sp 1
+should execute the sulogin command in single user mode.
+.PP
+As complete an environment as possible is created.
+However, various devices may be unmounted or uninitialized and many
+of the user commands may be unavailable or nonfunctional as a result.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- encrypted passwords and age information
+.br
+/.profile \- initialization script for single user shell
+.SH SEE ALSO
+.BR login (1),
+.BR init (8),
+.BR sh (1)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/useradd.8 b/current/man/useradd.8
new file mode 100644
index 00000000..aa84b755
--- /dev/null
+++ b/current/man/useradd.8
@@ -0,0 +1,197 @@
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: useradd.8,v 1.7 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH USERADD 8
+.SH NAME
+useradd \- Create a new user or update default new user information
+.SH SYNOPSIS
+.TP 8
+.B useradd
+.\" .RB [ -A
+.\" .RI { method | \fBDEFAULT\fR "},... ]"
+.RB [ -c
+.IR comment ]
+.RB [ -d
+.IR home_dir ]
+.br
+.RB [ -e
+.IR expire_date ]
+.RB [ -f
+.IR inactive_time ]
+.br
+.RB [ -g
+.IR initial_group ]
+.RB [ -G
+.IR group [,...]]
+.br
+.RB [ -m " [" -k
+.IR skeleton_dir ]]
+.RB [ -p
+.IR passwd ]
+.br
+.RB [ -s
+.IR shell ]
+.RB [ -u
+.IR uid " ["
+.BR -o ]]
+.I login
+.TP 8
+.B useradd
+\fB-D\fR
+[\fB-g\fI default_group\fR]
+[\fB-b\fI default_home\fR]
+.br
+[\fB-f\fI default_inactive\fR]
+[\fB-e\fI default_expire_date\fR]
+.br
+[\fB-s\fI default_shell\fR]
+.SH DESCRIPTION
+.SS Creating New Users
+When invoked without the \fB-D\fR option, the \fBuseradd\fR command
+creates a new user account using the values specified on the
+command line and the default values from the system.
+The new user account will be entered into the system files as needed,
+the home directory will be created, and initial files copied, depending
+on the command line options.
+The options which apply to the \fBuseradd\fR command are
+.\" .IP "\fB-A {\fImethod\fR|\fBDEFAULT\fR},..."
+.\" The value of the user's authentication method.
+.\" The authentication method is the name of a program which is responsible
+.\" for validating the user's identity.
+.\" The string \fBDEFAULT\fR may be used to change the user's authentication
+.\" method to the standard system password method.
+.\" This is a comma-separated list of program names.
+.\" It may include \fBDEFAULT\fR exactly once.
+.IP "\fB-c \fIcomment\fR"
+The new user's password file comment field.
+.IP "\fB-d \fIhome_dir\fR"
+The new user will be created using \fIhome_dir\fR as the value for
+the user's login directory.
+The default is to append the \fIlogin\fR name to \fIdefault_home\fR
+and use that as the login directory name.
+.IP "\fB-e \fIexpire_date\fR"
+The date on which the user account will be disabled.
+The date is specified in the format \fIYYYY-MM-DD\fR.
+.IP "\fB-f \fIinactive_days\fR"
+The number of days after a password expires until the account
+is permanently disabled.
+A value of 0 disables the account as soon as the password has
+expired, and a value of -1 disables the feature.
+The default value is -1.
+.IP "\fB-g \fIinitial_group\fR"
+The group name or number of the user's initial login group.
+The group name must exist. A group number must refer to an
+already existing group.
+The default group number is 1.
+.IP "\fB-G \fIgroup,[...]\fR"
+A list of supplementary groups which the user is also a member
+of.
+Each group is separated from the next by a comma, with no
+intervening whitespace.
+The groups are subject to the same restrictions as the group
+given with the \fB-g\fR option.
+The default is for the user to belong only to the initial group.
+.IP \fB-m\fR
+The user's home directory will be created if it does not exist.
+The files contained in \fIskeleton_dir\fR will be copied to the
+home directory if the \fB-k\fR option is used, otherwise the
+files contained in \fI/etc/skel\fR will be used instead.
+Any directories contained in \fIskeleton_dir\fR or \fI/etc/skel\fR
+will be created in the user's home directory as well.
+The \fB-k\fR option is only valid in conjunction with the \fB-m\fR
+option.
+The default is to not create the directory and to not copy any
+files.
+.IP "\fB-p \fIpasswd\fR"
+The encrypted password, as returned by \fBcrypt\fR(3).
+The default is to disable the account.
+.IP "\fB-s \fIshell\fR"
+The name of the user's login shell.
+The default is to leave this field blank, which causes the system
+to select the default login shell.
+.IP "\fB-u \fIuid\fR"
+The numerical value of the user's ID.
+This value must be unique, unless the \fI-o\fR option is used.
+The value must be non-negative.
+The default is to use the smallest ID value greater than 99 and
+greater than every other user.
+Values between 0 and 99 are typically reserved for system accounts.
+.SS Changing the default values
+When invoked with the \fB-D\fR option, \fBuseradd\fR will either
+display the current default values, or update the default values
+from the command line.
+The valid options are
+.IP "\fB-b \fIdefault_home\fR"
+The initial path prefix for a new user's home directory.
+The user's name will be affixed to the end of \fIdefault_home\fR
+to create the new directory name if the \fB-d\fI option is not
+used when creating a new account.
+.IP "\fB-e \fIdefault_expire_date\fR"
+The date on which the user account is disabled.
+.IP "\fB-f \fIdefault_inactive\fR"
+The number of days after a password has expired before the
+account will be disabled.
+.IP "\fB-g \fIdefault_group\fR"
+The group name or ID for a new user's initial group.
+The named group must exist, and a numerical group ID must have
+an existing entry .
+.IP "\fB-s \fIdefault_shell\fR"
+The name of the new user's login shell.
+The named program will be used for all future new user accounts.
+.PP
+If no options are specified, \fBuseradd\fR displays the current
+default values.
+.SH NOTES
+The system administrator is responsible for placing the default
+user files in the \fI/etc/skel\fR directory.
+.SH CAVEATS
+You may not add a user to an NIS group.
+This must be performed on the NIS server.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- secure user account information
+.br
+/etc/group \- group information
+.br
+/etc/default/useradd \- default information
+.br
+/etc/skel \- directory containing default files
+.SH SEE ALSO
+.BR chfn (1),
+.BR chsh (1),
+.BR crypt (3),
+.BR groupadd (8),
+.BR groupdel (8),
+.BR groupmod (8),
+.BR passwd (1),
+.BR userdel (8),
+.BR usermod (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/userdel.8 b/current/man/userdel.8
new file mode 100644
index 00000000..9a26713f
--- /dev/null
+++ b/current/man/userdel.8
@@ -0,0 +1,69 @@
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: userdel.8,v 1.5 2000/08/26 18:27:17 marekm Exp $
+.\"
+.TH USERDEL 8
+.SH NAME
+userdel \- Delete a user account and related files
+.SH SYNOPSIS
+.B userdel
+[\fB-r\fR]
+.I login
+.SH DESCRIPTION
+The \fBuserdel\fR command modifies the system account files, deleting
+all entries that refer to \fIlogin\fR.
+The named user must exist.
+.IP \fB-r\fR
+Files in the user's home directory will be removed along with the
+home directory itself and the user's mail spool.
+Files located in other file systems will have to be searched for
+and deleted manually.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- secure user account information
+.br
+/etc/group \- group information
+.SH CAVEATS
+\fBuserdel\fR will not allow you to remove an account if the user
+is currently logged in.
+You must kill any running processes which belong to an account that
+you are deleting.
+You may not remove any NIS attributes on an NIS client.
+This must be performed on the NIS server.
+.SH SEE ALSO
+.BR chfn (1),
+.BR chsh (1),
+.BR groupadd (8),
+.BR groupdel (8),
+.BR groupmod (8),
+.BR passwd (1),
+.BR useradd (8),
+.BR usermod (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/usermod.8 b/current/man/usermod.8
new file mode 100644
index 00000000..152514fd
--- /dev/null
+++ b/current/man/usermod.8
@@ -0,0 +1,162 @@
+.\" Copyright 1991 - 1994, Julianne Frances Haugh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: usermod.8,v 1.8 2000/09/02 18:40:43 marekm Exp $
+.\"
+.TH USERMOD 8
+.SH NAME
+usermod \- Modify a user account
+.SH SYNOPSIS
+.TP 8
+.B usermod
+.\" .RB [ -A
+.\" .RI { method | \fBDEFAULT\fR "},... ]"
+.RB [ -c
+.IR comment ]
+.RB [ -d
+.IR home_dir " ["
+.BR -m ]]
+.br
+.RB [ -e
+.IR expire_date ]
+.RB [ -f
+.IR inactive_time ]
+.br
+.RB [ -g
+.IR initial_group ]
+.RB [ -G
+.IR group [,...]]
+.br
+.RB [ -l
+.IR login_name ]
+.RB [ -p
+.IR passwd ]
+.br
+.RB [ -s
+.IR shell ]
+.RB [ -u
+.IR uid " ["
+.BR -o ]]
+.RB [ -L | -U ]
+.I login
+.SH DESCRIPTION
+The \fBusermod\fR command modifies the system account files to reflect
+the changes that are specified on the command line.
+The options which apply to the \fBusermod\fR command are
+.\" .IP "\fB-A \fImethod\fR|\fBDEFAULT\fR"
+.\" The new value of the user's authentication method.
+.\" The authentication method is the name of a program which is responsible
+.\" for validating the user's identity.
+.\" The string \fBDEFAULT\fR may be used to change the user's authentication
+.\" method to the standard system password method.
+.IP "\fB-c \fIcomment\fR"
+The new value of the user's password file comment field.
+It is normally modified using the \fBchfn\fR(1) utility.
+.IP "\fB-d \fIhome_dir\fR"
+The user's new login directory.
+If the \fB-m\fR option is given the contents of the current home directory
+will be moved to the new home directory, which is created if it does not
+already exist.
+.IP "\fB-e \fIexpire_date\fR"
+The date on which the user account will be disabled.
+The date is specified in the format \fIYYYY-MM-DD\fR.
+.IP "\fB-f \fIinactive_days\fR"
+The number of days after a password expires until the account
+is permanently disabled.
+A value of 0 disables the account as soon as the password has
+expired, and a value of -1 disables the feature.
+The default value is -1.
+.IP "\fB-g \fIinitial_group\fR"
+The group name or number of the user's new initial login group.
+The group name must exist. A group number must refer to an
+already existing group.
+The default group number is 1.
+.IP "\fB-G \fIgroup,[...]\fR"
+A list of supplementary groups which the user is also a member
+of.
+Each group is separated from the next by a comma, with no
+intervening whitespace.
+The groups are subject to the same restrictions as the group
+given with the \fB-g\fR option.
+If the user is currently a member of a group which is not listed,
+the user will be removed from the group
+.IP "\fB-l \fIlogin_name\fR"
+The name of the user will be changed from \fIlogin\fR to
+\fIlogin_name\fR.
+Nothing else is changed.
+In particular, the user's home directory name should probably
+be changed to reflect the new login name.
+.IP "\fB-p \fIpasswd\fR"
+The encrypted password, as returned by \fBcrypt\fR(3).
+.IP "\fB-s \fIshell\fR"
+The name of the user's new login shell.
+Setting this field to blank causes the system
+to select the default login shell.
+.IP "\fB-u \fIuid\fR"
+The numerical value of the user's ID.
+This value must be unique, unless the \fI-o\fR option is used.
+The value must be non-negative.
+Values between 0 and 99 are typically reserved for system accounts.
+Any files which the user owns and which are located in the directory
+tree rooted at the user's home directory will have the file user ID
+changed automatically.
+Files outside of the user's home directory must be altered manually.
+.IP "\fB-L\fR"
+Lock a user's password.
+This puts a '!' in front of the encrypted password, effectively disabling
+the password. You can't use this option with \fI-p\fR or \fI-U\fR.
+.IP "\fB-U\fR"
+Unlock a user's password.
+This removes the '!' in front of the encrypted password.
+You can't use this option with \fI-p\fR or \fI-L\fR.
+.SH CAVEATS
+\fBusermod\fR will not allow you to change the name of a user who is
+logged in.
+You must make certain that the named user is not executing any processes
+when this command is being executed if the user's numerical user ID is
+being changed.
+You must change the owner of any crontab files manually.
+You must change the owner of any at jobs manually.
+You must make any changes involving NIS on the NIS server.
+.SH FILES
+/etc/passwd \- user account information
+.br
+/etc/shadow \- secure user account information
+.br
+/etc/group \- group information
+.SH SEE ALSO
+.BR chfn (1),
+.BR chsh (1),
+.BR crypt (3),
+.BR groupadd (8),
+.BR groupdel (8),
+.BR groupmod (8),
+.BR passwd (1),
+.BR useradd (8),
+.BR userdel (8)
+.SH AUTHOR
+Julianne Frances Haugh (jfh@austin.ibm.com)
diff --git a/current/man/vipw.8 b/current/man/vipw.8
new file mode 100644
index 00000000..c8d3b3d4
--- /dev/null
+++ b/current/man/vipw.8
@@ -0,0 +1,29 @@
+.\" $Id: vipw.8,v 1.2 1997/12/14 20:07:22 marekm Exp $
+.TH VIPW 8 "26 Sep 1997"
+.SH NAME
+vipw, vigr \- edit the password, group, shadow-password, or shadow-group file.
+.SH SYNOPSIS
+.BR vipw " [-s]"
+.br
+.BR vigr " [-s]"
+.SH DESCRIPTION
+.BR vipw " and " vigr
+will edit the files
+.IR /etc/passwd " and " /etc/group ", respectively."
+With the
+.B -s
+flag, they will edit the shadow versions of those files,
+.IR /etc/shadow " and " /etc/gshadow ", respectively.
+The programs will set the appropriate locks to prevent file corruption.
+
+When looking for an editor, the programs will first try the
+environment variable
+.BR VISUAL ,
+then the environment variable
+.BR EDITOR ,
+and finally the default editor,
+.BR vi .
+.SH "SEE ALSO"
+.BR passwd (5),
+.BR group (5),
+.BR shadow (5)
diff --git a/current/missing b/current/missing
new file mode 100755
index 00000000..7789652e
--- /dev/null
+++ b/current/missing
@@ -0,0 +1,190 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing - GNU libit 0.0"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`configure.in'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`configure.in'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`configure.in'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/current/mkinstalldirs b/current/mkinstalldirs
new file mode 100755
index 00000000..4f58503e
--- /dev/null
+++ b/current/mkinstalldirs
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/current/po/ChangeLog b/current/po/ChangeLog
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/current/po/ChangeLog
diff --git a/current/po/Makefile.in.in b/current/po/Makefile.in.in
new file mode 100644
index 00000000..111b40fc
--- /dev/null
+++ b/current/po/Makefile.in.in
@@ -0,0 +1,248 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: cat-id-tbl.c $(CATALOGS)
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in \
+ && test ! -f $(PACKAGE).po \
+ || ( rm -f $(srcdir)/$(PACKAGE).pot \
+ && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot )
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r "$(MKINSTALLDIRS)"; then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r "$(MKINSTALLDIRS)"; then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r "$(MKINSTALLDIRS)"; then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+Makefile: Makefile.in.in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \
+ $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/po/POTFILES.in b/current/po/POTFILES.in
new file mode 100644
index 00000000..b04db505
--- /dev/null
+++ b/current/po/POTFILES.in
@@ -0,0 +1,123 @@
+# List of files which contain translatable strings.
+
+libmisc/addgrps.c
+libmisc/age.c
+libmisc/basename.c
+libmisc/chkname.c
+libmisc/chkshell.c
+libmisc/chowndir.c
+libmisc/chowntty.c
+libmisc/console.c
+libmisc/copydir.c
+libmisc/entry.c
+libmisc/env.c
+libmisc/failure.c
+libmisc/fields.c
+libmisc/hushed.c
+libmisc/isexpired.c
+libmisc/limits.c
+libmisc/list.c
+libmisc/log.c
+libmisc/login_access.c
+libmisc/login_desrpc.c
+libmisc/login_krb.c
+libmisc/loginprompt.c
+libmisc/mail.c
+libmisc/motd.c
+libmisc/myname.c
+libmisc/obscure.c
+libmisc/pam_pass.c
+libmisc/pwd2spwd.c
+libmisc/pwd_init.c
+libmisc/rlogin.c
+libmisc/salt.c
+libmisc/setugid.c
+libmisc/setup.c
+libmisc/setupenv.c
+libmisc/shell.c
+libmisc/strtoday.c
+libmisc/suauth.c
+libmisc/sub.c
+libmisc/sulog.c
+libmisc/ttytype.c
+libmisc/tz.c
+libmisc/ulimit.c
+libmisc/utmp.c
+libmisc/valid.c
+libmisc/xmalloc.c
+lib/commonio.c
+lib/dialchk.c
+lib/dialup.c
+lib/encrypt.c
+lib/fputsx.c
+lib/getdef.c
+lib/getpass.c
+lib/grdbm.c
+lib/groupio.c
+lib/grpack.c
+lib/gsdbm.c
+lib/gshadow.c
+lib/gspack.c
+lib/lockpw.c
+lib/md5.c
+lib/md5crypt.c
+lib/mkdir.c
+lib/port.c
+lib/putgrent.c
+lib/putpwent.c
+lib/putspent.c
+lib/pwauth.c
+lib/pwdbm.c
+lib/pwio.c
+lib/pwpack.c
+lib/rad64.c
+lib/rename.c
+lib/rmdir.c
+lib/sgetgrent.c
+lib/sgetpwent.c
+lib/sgetspent.c
+lib/sgroupio.c
+lib/shadow.c
+lib/shadowio.c
+lib/snprintf.c
+lib/spdbm.c
+lib/sppack.c
+lib/strcasecmp.c
+lib/strdup.c
+lib/strerror.c
+lib/strstr.c
+lib/tcfsio.c
+lib/utent.c
+src/chage.c
+src/chfn.c
+src/chpasswd.c
+src/chsh.c
+src/dpasswd.c
+src/expiry.c
+src/faillog.c
+src/gpasswd.c
+src/groupadd.c
+src/groupdel.c
+src/groupmod.c
+src/groups.c
+src/grpck.c
+src/grpconv.c
+src/grpunconv.c
+src/id.c
+src/lastlog.c
+src/login.c
+src/logoutd.c
+src/mkpasswd.c
+src/newgrp.c
+src/newusers.c
+src/passwd.c
+src/pwck.c
+src/pwconv.c
+src/pwunconv.c
+src/su.c
+src/sulogin.c
+src/useradd.c
+src/userdel.c
+src/usermod.c
+src/vipw.c
+
diff --git a/current/po/cat-id-tbl.c b/current/po/cat-id-tbl.c
new file mode 100644
index 00000000..314d8ca0
--- /dev/null
+++ b/current/po/cat-id-tbl.c
@@ -0,0 +1,504 @@
+/* Automatically generated by po2tbl.sed from shadow.pot. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libgettext.h"
+
+const struct _msg_ent _msg_tbl[] = {
+ {"", 1},
+ {"Warning: unknown group %s\n", 2},
+ {"Warning: too many groups\n", 3},
+ {"Your password has expired.", 4},
+ {"Your password is inactive.", 5},
+ {"Your login has expired.", 6},
+ {" Contact the system administrator.\n", 7},
+ {" Choose a new password.\n", 8},
+ {"Your password will expire in %ld days.\n", 9},
+ {"Your password will expire tomorrow.\n", 10},
+ {"Your password will expire today.\n", 11},
+ {"Unable to change tty %s", 12},
+ {"Environment overflow\n", 13},
+ {"You may not change $%s\n", 14},
+ {"%d %s since last login. Last was %s on %s.\n", 15},
+ {"failures", 16},
+ {"failure", 17},
+ {"Too many logins.\n", 18},
+ {"Password does not decrypt secret key for %s.\n", 19},
+ {"Could not set %s's secret key: is the keyserv daemon running?\n", 20},
+ {"You have new mail.", 21},
+ {"No mail.", 22},
+ {"You have mail.", 23},
+ {"Bad password: %s. ", 24},
+ {"passwd: pam_start() failed, error %d\n", 25},
+ {"passwd: %s\n", 26},
+ {"Unable to cd to \"%s\"\n", 27},
+ {"No directory, logging in with HOME=/", 28},
+ {"Executing shell %s\n", 29},
+ {"Cannot execute %s", 30},
+ {"Access to su to that account DENIED.\n", 31},
+ {"Password authentication bypassed.\n", 32},
+ {"Please enter your OWN password as authentication.\n", 33},
+ {"Invalid root directory \"%s\"\n", 34},
+ {"Can't change root directory to \"%s\"\n", 35},
+ {"malloc(%d) failed\n", 36},
+ {"Dialup Password: ", 37},
+ {"Could not allocate space for config info.\n", 38},
+ {"configuration error - unknown item '%s' (notify administrator)\n", 39},
+ {"error - lookup '%s' failed\n", 40},
+ {"%s not found\n", 41},
+ {"Password: ", 42},
+ {"%s's Password: ", 43},
+ {"(Echo on) ", 44},
+ {"Unknown error %d", 45},
+ {"\
+Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n\
+ [ -I inactive ] [ -E expire ] [ -d last_day ] user\n", 46},
+ {"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n", 47},
+ {"\
+Enter the new value, or press return for the default\n\
+\n", 48},
+ {"Minimum Password Age", 49},
+ {"Maximum Password Age", 50},
+ {"Last Password Change (YYYY-MM-DD)", 51},
+ {"Password Expiration Warning", 52},
+ {"Password Inactive", 53},
+ {"Account Expiration Date (YYYY-MM-DD)", 54},
+ {"Minimum:\t%ld\n", 55},
+ {"Maximum:\t%ld\n", 56},
+ {"Warning:\t%ld\n", 57},
+ {"Inactive:\t%ld\n", 58},
+ {"Last Change:\t\t", 59},
+ {"Never\n", 60},
+ {"Password Expires:\t", 61},
+ {"Password Inactive:\t", 62},
+ {"Account Expires:\t", 63},
+ {"%s: do not include \"l\" with other flags\n", 64},
+ {"%s: permission denied\n", 65},
+ {"%s: can't lock password file\n", 66},
+ {"%s: can't open password file\n", 67},
+ {"%s: unknown user: %s\n", 68},
+ {"%s: can't lock shadow password file\n", 69},
+ {"%s: can't open shadow password file\n", 70},
+ {"Changing the aging information for %s\n", 71},
+ {"%s: error changing fields\n", 72},
+ {"%s: can't update password file\n", 73},
+ {"%s: can't update shadow password file\n", 74},
+ {"Error updating the DBM password entry.\n", 75},
+ {"%s: can't rewrite shadow password file\n", 76},
+ {"%s: can't rewrite password file\n", 77},
+ {"%s: no aging information present\n", 78},
+ {"\
+Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n\
+\t[ -h home_ph ] [ -o other ] [ user ]\n", 79},
+ {"\
+Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n", 80},
+ {"Enter the new value, or press return for the default\n", 81},
+ {"Full Name", 82},
+ {"\tFull Name: %s\n", 83},
+ {"Room Number", 84},
+ {"\tRoom Number: %s\n", 85},
+ {"Work Phone", 86},
+ {"\tWork Phone: %s\n", 87},
+ {"Home Phone", 88},
+ {"\tHome Phone: %s\n", 89},
+ {"Other", 90},
+ {"%s: Permission denied.\n", 91},
+ {"%s: Unknown user %s\n", 92},
+ {"%s: Cannot determine your user name.\n", 93},
+ {"%s: cannot change user `%s' on NIS client.\n", 94},
+ {"%s: `%s' is the NIS master for this client.\n", 95},
+ {"Changing the user information for %s\n", 96},
+ {"%s: invalid name: \"%s\"\n", 97},
+ {"%s: invalid room number: \"%s\"\n", 98},
+ {"%s: invalid work phone: \"%s\"\n", 99},
+ {"%s: invalid home phone: \"%s\"\n", 100},
+ {"%s: \"%s\" contains illegal characters\n", 101},
+ {"%s: fields too long\n", 102},
+ {"Cannot change ID to root.\n", 103},
+ {"Cannot lock the password file; try again later.\n", 104},
+ {"Cannot open the password file.\n", 105},
+ {"%s: %s not found in /etc/passwd\n", 106},
+ {"Error updating the password entry.\n", 107},
+ {"Cannot commit password file changes.\n", 108},
+ {"Cannot unlock the password file.\n", 109},
+ {"usage: %s [-e]\n", 110},
+ {"%s: can't lock shadow file\n", 111},
+ {"%s: can't open shadow file\n", 112},
+ {"%s: line %d: line too long\n", 113},
+ {"%s: line %d: missing new password\n", 114},
+ {"%s: line %d: unknown user %s\n", 115},
+ {"%s: line %d: cannot update password entry\n", 116},
+ {"%s: error detected, changes ignored\n", 117},
+ {"%s: error updating shadow file\n", 118},
+ {"%s: error updating password file\n", 119},
+ {"Usage: %s [ -s shell ] [ name ]\n", 120},
+ {"Login Shell", 121},
+ {"You may not change the shell for %s.\n", 122},
+ {"Changing the login shell for %s\n", 123},
+ {"%s: Invalid entry: %s\n", 124},
+ {"%s is an invalid shell.\n", 125},
+ {"Usage: %s [ -(a|d) ] shell\n", 126},
+ {"Shell password: ", 127},
+ {"re-enter Shell password: ", 128},
+ {"%s: Passwords do not match, try again.\n", 129},
+ {"%s: can't create %s", 130},
+ {"%s: can't open %s", 131},
+ {"%s: Shell %s not found.\n", 132},
+ {"Usage: expiry { -f | -c }\n", 133},
+ {"%s: WARNING! Must be set-UID root!\n", 134},
+ {"%s: unknown user\n", 135},
+ {"usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n", 136},
+ {"Unknown User: %s\n", 137},
+ {"Username Failures Maximum Latest\n", 138},
+ {" %s on %s", 139},
+ {" [%lds left]", 140},
+ {" [%lds lock]", 141},
+ {"usage: %s [-r|-R] group\n", 142},
+ {" %s [-a user] group\n", 143},
+ {" %s [-d user] group\n", 144},
+ {" %s [-A user,...] [-M user,...] group\n", 145},
+ {" %s [-M user,...] group\n", 146},
+ {"%s: unknown user %s\n", 147},
+ {"Permission denied.\n", 148},
+ {"%s: shadow group passwords required for -A\n", 149},
+ {"Who are you?\n", 150},
+ {"unknown group: %s\n", 151},
+ {"Adding user %s to group %s\n", 152},
+ {"Removing user %s from group %s\n", 153},
+ {"%s: unknown member %s\n", 154},
+ {"%s: Not a tty\n", 155},
+ {"Changing the password for group %s\n", 156},
+ {"New Password: ", 157},
+ {"Re-enter new password: ", 158},
+ {"They don't match; try again", 159},
+ {"%s: Try again later\n", 160},
+ {"%s: can't get lock\n", 161},
+ {"%s: can't get shadow lock\n", 162},
+ {"%s: can't open file\n", 163},
+ {"%s: can't update entry\n", 164},
+ {"%s: can't update shadow entry\n", 165},
+ {"%s: can't re-write file\n", 166},
+ {"%s: can't re-write shadow file\n", 167},
+ {"%s: can't unlock file\n", 168},
+ {"%s: can't update DBM files\n", 169},
+ {"%s: can't update DBM shadow files\n", 170},
+ {"usage: groupadd [-g gid [-o]] group\n", 171},
+ {"%s: error adding new group entry\n", 172},
+ {"%s: cannot add new dbm group entry\n", 173},
+ {"%s: name %s is not unique\n", 174},
+ {"%s: gid %ld is not unique\n", 175},
+ {"%s: can't get unique gid\n", 176},
+ {"%s: %s is a not a valid group name\n", 177},
+ {"%s: invalid group %s\n", 178},
+ {"%s: -O requires NAME=VALUE\n", 179},
+ {"%s: cannot rewrite group file\n", 180},
+ {"%s: cannot rewrite shadow group file\n", 181},
+ {"%s: unable to lock group file\n", 182},
+ {"%s: unable to open group file\n", 183},
+ {"%s: unable to lock shadow group file\n", 184},
+ {"%s: unable to open shadow group file\n", 185},
+ {"%s: group %s exists\n", 186},
+ {"usage: groupdel group\n", 187},
+ {"%s: error removing group entry\n", 188},
+ {"%s: error removing group dbm entry\n", 189},
+ {"%s: error removing shadow group entry\n", 190},
+ {"%s: error removing shadow group dbm entry\n", 191},
+ {"%s: cannot remove user's primary group.\n", 192},
+ {"%s: group %s does not exist\n", 193},
+ {"%s: group %s is a NIS group\n", 194},
+ {"%s: %s is the NIS master\n", 195},
+ {"usage: groupmod [-g gid [-o]] [-n name] group\n", 196},
+ {"%s: %s not found in /etc/group\n", 197},
+ {"%s: cannot add new dbm shadow group entry\n", 198},
+ {"%s: %ld is not a unique gid\n", 199},
+ {"%s: %s is not a unique name\n", 200},
+ {"unknown user %s\n", 201},
+ {"Usage: %s [ -r ] [ group [ gshadow ] ]\n", 202},
+ {"Usage: %s [ -r ] [ group ]\n", 203},
+ {"No", 204},
+ {"%s: cannot lock file %s\n", 205},
+ {"%s: cannot open file %s\n", 206},
+ {"invalid group file entry\n", 207},
+ {"delete line `%s'? ", 208},
+ {"duplicate group entry\n", 209},
+ {"invalid group name `%s'\n", 210},
+ {"group %s: bad GID (%d)\n", 211},
+ {"group %s: no user %s\n", 212},
+ {"delete member `%s'? ", 213},
+ {"invalid shadow group file entry\n", 214},
+ {"duplicate shadow group entry\n", 215},
+ {"no matching group file entry\n", 216},
+ {"shadow group %s: no administrative user %s\n", 217},
+ {"delete administrative member `%s'? ", 218},
+ {"shadow group %s: no user %s\n", 219},
+ {"%s: cannot update file %s\n", 220},
+ {"%s: the files have been updated; run mkpasswd\n", 221},
+ {"%s: no changes\n", 222},
+ {"%s: the files have been updated\n", 223},
+ {"%s: can't lock group file\n", 224},
+ {"%s: can't open group file\n", 225},
+ {"%s: can't lock shadow group file\n", 226},
+ {"%s: can't open shadow group file\n", 227},
+ {"%s: can't remove shadow group %s\n", 228},
+ {"%s: can't update shadow entry for %s\n", 229},
+ {"%s: can't update entry for group %s\n", 230},
+ {"%s: can't update shadow group file\n", 231},
+ {"%s: can't update group file\n", 232},
+ {"%s: not configured for shadow group support.\n", 233},
+ {"%s: can't delete shadow group file\n", 234},
+ {"usage: id [ -a ]\n", 235},
+ {"usage: id\n", 236},
+ {"uid=%d(%s)", 237},
+ {"uid=%d", 238},
+ {" gid=%d(%s)", 239},
+ {" gid=%d", 240},
+ {" euid=%d(%s)", 241},
+ {" euid=%d", 242},
+ {" egid=%d(%s)", 243},
+ {" egid=%d", 244},
+ {" groups=", 245},
+ {"Username Port From Latest\n", 246},
+ {"Username Port Latest\n", 247},
+ {"**Never logged in**", 248},
+ {"usage: %s [-p] [name]\n", 249},
+ {" %s [-p] [-h host] [-f name]\n", 250},
+ {" %s [-p] -r host\n", 251},
+ {"Invalid login time\n", 252},
+ {"\
+\n\
+System closed for routine maintenance\n", 253},
+ {"\
+\n\
+[Disconnect bypassed -- root login allowed.]\n", 254},
+ {"\
+\n\
+Login timed out after %d seconds.\n", 255},
+ {" on `%.100s' from `%.200s'", 256},
+ {" on `%.100s'", 257},
+ {"\
+\n\
+%s login: ", 258},
+ {"login: ", 259},
+ {"Login incorrect", 260},
+ {"Warning: login re-enabled after temporary lockout.\n", 261},
+ {"Last login: %s on %s", 262},
+ {"Last login: %.19s on %s", 263},
+ {" from %.*s", 264},
+ {"Starting rad_login\n", 265},
+ {"%s: no DBM database on system - no action performed\n", 266},
+ {"%s: cannot overwrite file %s\n", 267},
+ {"%s: cannot open DBM files for %s\n", 268},
+ {"%s: the beginning with ", 269},
+ {"%s: error parsing line \"%s\"\n", 270},
+ {"adding record for name ", 271},
+ {"%s: error adding record for ", 272},
+ {"added %d entries, longest was %d\n", 273},
+ {"Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n", 274},
+ {"Usage: %s [ -vf ] [ -p|g|sp ] file\n", 275},
+ {"Usage: %s [ -vf ] [ -p|g ] file\n", 276},
+ {"usage: newgrp [ - ] [ group ]\n", 277},
+ {"usage: sg group [[-c] command ]\n", 278},
+ {"unknown uid: %d\n", 279},
+ {"unknown gid: %ld\n", 280},
+ {"unknown gid: %d\n", 281},
+ {"Sorry.\n", 282},
+ {"too many groups\n", 283},
+ {"Usage: %s [ input ]\n", 284},
+ {"%s: can't lock /etc/passwd.\n", 285},
+ {"%s: can't lock files, try again later\n", 286},
+ {"%s: can't open files\n", 287},
+ {"%s: line %d: invalid line\n", 288},
+ {"%s: line %d: can't create GID\n", 289},
+ {"%s: line %d: can't create UID\n", 290},
+ {"%s: line %d: cannot find user %s\n", 291},
+ {"%s: line %d: can't update password\n", 292},
+ {"%s: line %d: mkdir failed\n", 293},
+ {"%s: line %d: chown failed\n", 294},
+ {"%s: line %d: can't update entry\n", 295},
+ {"%s: error updating files\n", 296},
+ {"usage: %s [ -f | -s ] [ name ]\n", 297},
+ {" %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n", 298},
+ {" %s { -l | -u | -d | -S | -e } name\n", 299},
+ {"User %s has a TCFS key, his old password is required.\n", 300},
+ {"You can use -t option to force the change.\n", 301},
+ {"Old password: ", 302},
+ {"Incorrect password for `%s'\n", 303},
+ {"Warning: user %s has a TCFS key.\n", 304},
+ {"\
+Enter the new password (minimum of %d, maximum of %d characters)\n\
+Please use a combination of upper and lower case letters and numbers.\n", 305},
+ {"New password: ", 306},
+ {"Try again.\n", 307},
+ {"\
+\n\
+Warning: weak password (enter it again to use it anyway).\n", 308},
+ {"They don't match; try again.\n", 309},
+ {"The password for %s cannot be changed.\n", 310},
+ {"Sorry, the password for %s cannot be changed yet.\n", 311},
+ {"%s: out of memory\n", 312},
+ {"Cannot lock the TCFS key database; try again later\n", 313},
+ {"Cannot open the TCFS key database.\n", 314},
+ {"Error updating the TCFS key database.\n", 315},
+ {"Cannot commit TCFS changes.\n", 316},
+ {"%s: Cannot execute %s", 317},
+ {"%s: repository %s not supported\n", 318},
+ {"%s: Permission denied\n", 319},
+ {"You may not change the password for %s.\n", 320},
+ {"Changing password for %s\n", 321},
+ {"The password for %s is unchanged.\n", 322},
+ {"Password changed.\n", 323},
+ {"Usage: %s [ -qr ] [ passwd [ shadow ] ]\n", 324},
+ {"Usage: %s [ -qr ] [ passwd ]\n", 325},
+ {"invalid password file entry\n", 326},
+ {"duplicate password entry\n", 327},
+ {"invalid user name `%s'\n", 328},
+ {"user %s: bad UID (%d)\n", 329},
+ {"user %s: no group %d\n", 330},
+ {"user %s: directory %s does not exist\n", 331},
+ {"user %s: program %s does not exist\n", 332},
+ {"invalid shadow password file entry\n", 333},
+ {"duplicate shadow password entry\n", 334},
+ {"no matching password file entry\n", 335},
+ {"user %s: last password change in the future\n", 336},
+ {"%s: can't lock passwd file\n", 337},
+ {"%s: can't open passwd file\n", 338},
+ {"%s: can't remove shadow entry for %s\n", 339},
+ {"%s: can't update passwd entry for %s\n", 340},
+ {"%s: can't update shadow file\n", 341},
+ {"%s: can't update passwd file\n", 342},
+ {"%s: Shadow passwords are not configured.\n", 343},
+ {"%s: can't update entry for user %s\n", 344},
+ {"%s: can't delete shadow password file\n", 345},
+ {"Sorry.", 346},
+ {"%s: must be run from a terminal\n", 347},
+ {"%s: pam_start: error %d\n", 348},
+ {"Unknown id: %s\n", 349},
+ {"You are not authorized to su %s\n", 350},
+ {"(Enter your own password.)", 351},
+ {"%s: permission denied (shell).\n", 352},
+ {"\
+%s: %s\n\
+(Ignored)\n", 353},
+ {"No shell\n", 354},
+ {"No password file\n", 355},
+ {"No password entry for 'root'\n", 356},
+ {"\
+\n\
+Type control-d to proceed with normal startup,\n\
+(or give root password for system maintenance):", 357},
+ {"Entering System Maintenance Mode\n", 358},
+ {"%s: rebuild the group database\n", 359},
+ {"%s: rebuild the shadow group database\n", 360},
+ {"%s: invalid numeric argument `%s'\n", 361},
+ {"%s: unknown gid %s\n", 362},
+ {"%s: unknown group %s\n", 363},
+ {"group=%s,%ld basedir=%s skel=%s\n", 364},
+ {"shell=%s ", 365},
+ {"inactive=%ld expire=%s", 366},
+ {"GROUP=%ld\n", 367},
+ {"HOME=%s\n", 368},
+ {"INACTIVE=%ld\n", 369},
+ {"EXPIRE=%s\n", 370},
+ {"SHELL=%s\n", 371},
+ {"SKEL=%s\n", 372},
+ {"%s: cannot create new defaults file\n", 373},
+ {"%s: rename: %s", 374},
+ {"%s: group `%s' is a NIS group.\n", 375},
+ {"%s: too many groups specified (max %d).\n", 376},
+ {"usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n", 377},
+ {"\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n", 378},
+ {"[-f inactive] [-e expire ] ", 379},
+ {"[-A program] ", 380},
+ {"[-p passwd] name\n", 381},
+ {" %s\t-D [-g group] [-b base] [-s shell]\n", 382},
+ {"\t\t[-f inactive] [-e expire ]\n", 383},
+ {"%s: error locking group file\n", 384},
+ {"%s: error opening group file\n", 385},
+ {"%s: error locking shadow group file\n", 386},
+ {"%s: error opening shadow group file\n", 387},
+ {"%s: uid %d is not unique\n", 388},
+ {"%s: can't get unique uid\n", 389},
+ {"%s: invalid field `%s'\n", 390},
+ {"%s: invalid base directory `%s'\n", 391},
+ {"%s: invalid comment `%s'\n", 392},
+ {"%s: invalid home directory `%s'\n", 393},
+ {"%s: invalid date `%s'\n", 394},
+ {"%s: shadow passwords required for -e\n", 395},
+ {"%s: shadow passwords required for -f\n", 396},
+ {"%s: invalid shell `%s'\n", 397},
+ {"%s: invalid user name `%s'\n", 398},
+ {"%s: cannot rewrite password file\n", 399},
+ {"%s: cannot rewrite shadow password file\n", 400},
+ {"%s: unable to lock password file\n", 401},
+ {"%s: unable to open password file\n", 402},
+ {"%s: cannot lock shadow password file\n", 403},
+ {"%s: cannot open shadow password file\n", 404},
+ {"%s: error adding authentication method\n", 405},
+ {"%s: error adding new password entry\n", 406},
+ {"%s: error updating password dbm entry\n", 407},
+ {"%s: error adding new shadow password entry\n", 408},
+ {"%s: error updating shadow passwd dbm entry\n", 409},
+ {"%s: cannot create directory %s\n", 410},
+ {"%s: user %s exists\n", 411},
+ {"%s: warning: CREATE_HOME not supported, please use -m instead.\n", 412},
+ {"usage: %s [-r] name\n", 413},
+ {"%s: error updating group entry\n", 414},
+ {"%s: cannot update dbm group entry\n", 415},
+ {"%s: cannot remove dbm group entry\n", 416},
+ {"%s: cannot rewrite TCFS key file\n", 417},
+ {"%s: cannot lock TCFS key file\n", 418},
+ {"%s: cannot open TCFS key file\n", 419},
+ {"%s: cannot open group file\n", 420},
+ {"%s: cannot open shadow group file\n", 421},
+ {"%s: error deleting authentication\n", 422},
+ {"%s: error deleting password entry\n", 423},
+ {"%s: error deleting shadow password entry\n", 424},
+ {"%s: error deleting TCFS entry\n", 425},
+ {"%s: error deleting password dbm entry\n", 426},
+ {"%s: error deleting shadow passwd dbm entry\n", 427},
+ {"%s: user %s is currently logged in\n", 428},
+ {"%s: warning: %s not owned by %s, not removing\n", 429},
+ {"%s: warning: can't remove ", 430},
+ {"%s: user %s does not exist\n", 431},
+ {"%s: user %s is a NIS user\n", 432},
+ {"%s: %s not owned by %s, not removing\n", 433},
+ {"%s: not removing directory %s (would remove home of user %s)\n", 434},
+ {"%s: error removing directory %s\n", 435},
+ {"\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n", 436},
+ {"[-A {DEFAULT|program},... ] ", 437},
+ {"[-p passwd] [-L|-U] name\n", 438},
+ {"%s: out of memory in update_group\n", 439},
+ {"%s: out of memory in update_gshadow\n", 440},
+ {"%s: no flags given\n", 441},
+ {"%s: shadow passwords required for -e and -f\n", 442},
+ {"%s: uid %ld is not unique\n", 443},
+ {"%s: error deleting authentication method\n", 444},
+ {"%s: error changing authentication method\n", 445},
+ {"%s: error changing password entry\n", 446},
+ {"%s: error removing password entry\n", 447},
+ {"%s: error adding password dbm entry\n", 448},
+ {"%s: error removing passwd dbm entry\n", 449},
+ {"%s: error removing shadow password entry\n", 450},
+ {"%s: error removing shadow passwd dbm entry\n", 451},
+ {"%s: directory %s exists\n", 452},
+ {"%s: can't create %s\n", 453},
+ {"%s: can't chown %s\n", 454},
+ {"%s: cannot rename directory %s to %s\n", 455},
+ {"%s: warning: %s not owned by %s\n", 456},
+ {"failed to change mailbox owner", 457},
+ {"failed to rename mailbox", 458},
+ {"\
+\n\
+%s: %s is unchanged\n", 459},
+ {"Couldn't lock file", 460},
+ {"Couldn't make backup", 461},
+ {"%s: can't restore %s: %s (your changes are in %s)\n", 462},
+ {"\
+Usage:\n\
+`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n\
+`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n", 463},
+};
+
+int _msg_tbl_length = 463;
diff --git a/current/po/el.gmo b/current/po/el.gmo
new file mode 100644
index 00000000..15311f73
--- /dev/null
+++ b/current/po/el.gmo
Binary files differ
diff --git a/current/po/el.po b/current/po/el.po
new file mode 100644
index 00000000..16f129d5
--- /dev/null
+++ b/current/po/el.po
@@ -0,0 +1,2459 @@
+# Shadow Password Suite
+# Greek Translation by Nikos Mavroyanopoulos
+# Thanks to Simos Xenitelis (S.Xenitellis@rhbnc.ac.uk) for his
+# comments about making this translation better.
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Shadow 980726\n"
+"POT-Creation-Date: 2000-09-02 20:40+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>\n"
+"Language-Team: Hellenic <el@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO8859-7\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: libmisc/addgrps.c:60
+#, c-format
+msgid "Warning: unknown group %s\n"
+msgstr "Ðñïåéäïðïßçóç: Üãíùóôç ïìÜäá %s\n"
+
+#: libmisc/addgrps.c:71
+msgid "Warning: too many groups\n"
+msgstr "Ðñïåéäïðïßçóç: ÐïëëÝò ïìÜäåò\n"
+
+#: libmisc/age.c:104
+msgid "Your password has expired."
+msgstr "Ôï óõíèçìáôéêü óáò Ý÷åé ëÞîåé."
+
+#: libmisc/age.c:107
+msgid "Your password is inactive."
+msgstr "Ôï óõíèçìáôéêü óáò åßíáé áíåíåñãü."
+
+#: libmisc/age.c:110
+msgid "Your login has expired."
+msgstr "Ï êùäéêüò åéóüäïõ óáò Ý÷åé ëÞîåé."
+
+#: libmisc/age.c:127
+msgid " Contact the system administrator.\n"
+msgstr " ÅðéêïéíùíÞóôå ìå ôïí äéá÷åéñéóôÞ ôïõ óõóôÞìáôïò.\n"
+
+#: libmisc/age.c:130
+msgid " Choose a new password.\n"
+msgstr " ÅðéëÝîôå Ýíá íÝï óõíèçìáôéêü.\n"
+
+#: libmisc/age.c:228
+#, c-format
+msgid "Your password will expire in %ld days.\n"
+msgstr "Ôï óõíèçìáôéêü óáò èá ëÞîåé óå %ld ìÝñåò.\n"
+
+#: libmisc/age.c:230
+msgid "Your password will expire tomorrow.\n"
+msgstr "Ôï óõíèçìáôéêü óáò èá ëÞîåé áýñéï.\n"
+
+#: libmisc/age.c:232
+msgid "Your password will expire today.\n"
+msgstr "Ôï óõíèçìáôéêü óáò èá ëÞîåé óÞìåñá.\n"
+
+#: libmisc/chowntty.c:110
+#, c-format
+msgid "Unable to change tty %s"
+msgstr "Áäõíáìßá áëëáãÞò tty %s"
+
+#: libmisc/env.c:160
+msgid "Environment overflow\n"
+msgstr "Õðåñ÷åßëéóç ðåñéâÜëëïíôïò\n"
+
+#: libmisc/env.c:200
+#, c-format
+msgid "You may not change $%s\n"
+msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôï $%s\n"
+
+#: libmisc/failure.c:238
+#, c-format
+msgid "%d %s since last login. Last was %s on %s.\n"
+msgstr "%d %s áðü ôçí ôåëåõôáßá åßóïäï. Ç ôåëåõôáßá Þôáí óôéò %s óôï %s.\n"
+
+#: libmisc/failure.c:239
+msgid "failures"
+msgstr "áðïôõ÷ßåò"
+
+#: libmisc/failure.c:239
+msgid "failure"
+msgstr "áðïôõ÷ßá"
+
+#: libmisc/limits.c:397
+msgid "Too many logins.\n"
+msgstr "ÐïëëÝò åßóïäïé óôï óýóôçìá.\n"
+
+#: libmisc/login_desrpc.c:63
+#, c-format
+msgid "Password does not decrypt secret key for %s.\n"
+msgstr "Ôï óõíèçìáôéêü äåí áðïêùäéêïðïéåß ôï ìõóôéêü êëåéäß ãéá ôï(í) %s.\n"
+
+#: libmisc/login_desrpc.c:69
+#, c-format
+msgid "Could not set %s's secret key: is the keyserv daemon running?\n"
+msgstr ""
+"Äåí åßíáé äõíáôüí íá ôåèåß ôï ìõóôéêü êëåéäß ôïõ %s: Åêôåëåßôáé ï\n"
+"äéáêïìéóôÞò êëåéäéþí;\n"
+
+#: libmisc/mail.c:62 libmisc/mail.c:77
+msgid "You have new mail."
+msgstr "¸÷åôå íÝá ãñÜììáôá."
+
+#: libmisc/mail.c:73
+msgid "No mail."
+msgstr "ÊáíÝíá ãñÜììá."
+
+#: libmisc/mail.c:75
+msgid "You have mail."
+msgstr "¸÷åôå ãñÜììáôá."
+
+#: libmisc/obscure.c:281 src/passwd.c:309
+#, c-format
+msgid "Bad password: %s. "
+msgstr "Êáêü óõíèçìáôéêü: %s. "
+
+#: libmisc/pam_pass.c:42
+#, c-format
+msgid "passwd: pam_start() failed, error %d\n"
+msgstr "óõíèçìáôéêü: pam_start() áðÝôõ÷å, óöÜëìá %d\n"
+
+#: libmisc/pam_pass.c:49
+#, c-format
+msgid "passwd: %s\n"
+msgstr "óõíèçìáôéêü: %s\n"
+
+#: libmisc/setupenv.c:205
+#, c-format
+msgid "Unable to cd to \"%s\"\n"
+msgstr "Áäõíáìßá áëëáãÞò êáôáëüãïõ óôïí \"%s\"\n"
+
+#: libmisc/setupenv.c:213
+msgid "No directory, logging in with HOME=/"
+msgstr "×ùñßò êáôÜëïãï, åéóáãùãÞ ìå ÌÇÔÑÉÊÏ_ÊÁÔÁËÏÃÏ=/"
+
+#: libmisc/shell.c:78
+#, c-format
+msgid "Executing shell %s\n"
+msgstr "ÅêôÝëåóç öëïéïý %s\n"
+
+#.
+#. * Obviously something is really wrong - I can't figure out
+#. * how to execute this stupid shell, so I might as well give
+#. * up in disgust ...
+#.
+#: libmisc/shell.c:122
+#, c-format
+msgid "Cannot execute %s"
+msgstr "Áäõíáìßá åêôÝëåóçò %s"
+
+#: libmisc/suauth.c:99
+msgid "Access to su to that account DENIED.\n"
+msgstr "Ðñüóâáóç óôç su óå áõôüí ôïí ëïãáñéáóìü ÁÑÍÇÈÇÊÅ.\n"
+
+#: libmisc/suauth.c:106
+msgid "Password authentication bypassed.\n"
+msgstr "ÐáñÜêáìøç åîáêñßâùóçò ìå óõíèçìáôéêü.\n"
+
+#: libmisc/suauth.c:113
+msgid "Please enter your OWN password as authentication.\n"
+msgstr "Ðáñáêáëþ åéóÜãåôå ôï ÄÉÊÏ óáò óõíèçìáôéêü ãéá åîáêñßâùóç.\n"
+
+#: libmisc/sub.c:61
+#, c-format
+msgid "Invalid root directory \"%s\"\n"
+msgstr "Ìç Ýãêõñïò ðñùôáñ÷éêüò êáôÜëïãïò \"%s\"\n"
+
+#: libmisc/sub.c:73
+#, c-format
+msgid "Can't change root directory to \"%s\"\n"
+msgstr "Áäõíáìßá áëëáãÞò ôïõ ðñùôáñ÷éêïý êáôáëüãïõ óå \"%s\"\n"
+
+#: libmisc/xmalloc.c:28
+#, c-format
+msgid "malloc(%d) failed\n"
+msgstr "Ç êëÞóç malloc(%d) áðÝôõ÷å\n"
+
+#: lib/dialchk.c:71
+msgid "Dialup Password: "
+msgstr "Óõíèçìáôéêü ôçëåöùíéêÞò óýíäåóçò: "
+
+#: lib/getdef.c:253
+msgid "Could not allocate space for config info.\n"
+msgstr "Áäõíáìßá äÝóìåõóçò ÷þñïõ ãéá ðëçñïöïñßåò äéáìüñöùóçò.\n"
+
+#.
+#. * Item was never found.
+#.
+#: lib/getdef.c:307
+#, c-format
+msgid "configuration error - unknown item '%s' (notify administrator)\n"
+msgstr ""
+"óöÜëìá äéáìüñöùóçò - Üãíùóôï áíôéêåßìåíï '%s' (åéäïðïéåßóôå ôïí "
+"äéá÷åéñéóôÞ)\n"
+
+#: lib/getdef.c:394
+#, c-format
+msgid "error - lookup '%s' failed\n"
+msgstr "óöÜëìá - ç áíáæÞôçóç '%s' áðÝôõ÷å\n"
+
+#: lib/getdef.c:402
+#, c-format
+msgid "%s not found\n"
+msgstr "%s äåí âñÝèçêå\n"
+
+#.
+#. * get the password from her, and set the salt for
+#. * the decryption from the group file.
+#.
+#: lib/pwauth.c:54 src/newgrp.c:305
+msgid "Password: "
+msgstr "Óõíèçìáôéêü: "
+
+#: lib/pwauth.c:56
+#, c-format
+msgid "%s's Password: "
+msgstr "Ôïõ %s ôï Óõíèçìáôéêü: "
+
+#: lib/pwauth.c:270
+msgid "(Echo on) "
+msgstr ""
+
+#: lib/strerror.c:20
+#, c-format
+msgid "Unknown error %d"
+msgstr "Áãíùóôï óöÜëìá %d"
+
+#: src/chage.c:156
+#, c-format
+msgid ""
+"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n"
+" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"
+msgstr ""
+"×ñÞóç: %s [ -l ] [ -m åëá÷_ìÝñåò ] [ -M ìåã_ìÝñåò ] [ -W ðñïåéä. ]\n"
+"\t[ -I áíåíåñãü ] [ -E ëÞîç ] [ -d ôåëåõôáßá_ìÝñá ] ÷ñÞóôçò\n"
+
+#: src/chage.c:158
+#, c-format
+msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"
+msgstr ""
+"×ñÞóç: %s [ -l ] [ -m åëÜ÷_ìÝñåò ] [ -M ìåã_ìÝñåò ]\n"
+"[ -d ôåëåõôáßá_ìÝñá ] ÷ñÞóôçò\n"
+
+#: src/chage.c:193
+msgid ""
+"Enter the new value, or press return for the default\n"
+"\n"
+msgstr ""
+"ÅéóÜãåôå ôçí íÝá ôéìÞ, Þ ðéÝóôå `return' ãéá ôçí ðñïêáèïñéóìÝíç\n"
+"\n"
+
+#: src/chage.c:196
+msgid "Minimum Password Age"
+msgstr "Ìéêñüôåñç äéÜñêåéá óõíèçìáôéêïý"
+
+#: src/chage.c:201
+msgid "Maximum Password Age"
+msgstr "ÌÝãéóôç äéÜñêåéá óõíèçìáôéêïý"
+
+#: src/chage.c:207
+msgid "Last Password Change (YYYY-MM-DD)"
+msgstr "Ôåëåõôáßá áëëáãÞ óõíèçìáôéêïý (××××-ÌÌ-ÇÇ)"
+
+#: src/chage.c:216
+msgid "Password Expiration Warning"
+msgstr "Ðñïåéäïðïßçóç ëÞîçò óõíèçìáôéêïý"
+
+#: src/chage.c:221
+msgid "Password Inactive"
+msgstr "Áíåíåñãü óõíèçìáôéêü"
+
+#: src/chage.c:227
+msgid "Account Expiration Date (YYYY-MM-DD)"
+msgstr "Çìåñïìçíßá ËÞîçò Ëïãáñéáóìïý (××××-ÌÌ-ÇÇ)"
+
+#.
+#. * Start with the easy numbers - the number of days before the
+#. * password can be changed, the number of days after which the
+#. * password must be chaged, the number of days before the
+#. * password expires that the user is told, and the number of
+#. * days after the password expires that the account becomes
+#. * unusable.
+#.
+#: src/chage.c:281
+#, c-format
+msgid "Minimum:\t%ld\n"
+msgstr "ÅëÜ÷éóôï:\t%ld\n"
+
+#: src/chage.c:282
+#, c-format
+msgid "Maximum:\t%ld\n"
+msgstr "ÌÝãéóôï:\t%ld\n"
+
+#: src/chage.c:284
+#, c-format
+msgid "Warning:\t%ld\n"
+msgstr "Ðñïåéäïðïßçóç:\t%ld\n"
+
+#: src/chage.c:285
+#, c-format
+msgid "Inactive:\t%ld\n"
+msgstr "Áíåíåñãüò:\t%ld\n"
+
+#.
+#. * The "last change" date is either "Never" or the date the
+#. * password was last modified. The date is the number of
+#. * days since 1/1/1970.
+#.
+#: src/chage.c:294
+msgid "Last Change:\t\t"
+msgstr "Ôåëåõôáßá áëëáãÞ:\t\t"
+
+#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340
+msgid "Never\n"
+msgstr "ÐïôÝ\n"
+
+#.
+#. * The password expiration date is determined from the last
+#. * change date plus the number of days the password is valid
+#. * for.
+#.
+#: src/chage.c:308
+msgid "Password Expires:\t"
+msgstr "Ôï óõíèçìáôéêü ëÞãåé:\t"
+
+#.
+#. * The account becomes inactive if the password is expired
+#. * for more than "inactdays". The expiration date is calculated
+#. * and the number of inactive days is added. The resulting date
+#. * is when the active will be disabled.
+#.
+#: src/chage.c:324
+#, fuzzy
+msgid "Password Inactive:\t"
+msgstr "Áíåíåñãü óõíèçìáôéêü"
+
+#.
+#. * The account will expire on the given date regardless of the
+#. * password expiring or not.
+#.
+#: src/chage.c:338
+#, fuzzy
+msgid "Account Expires:\t"
+msgstr "Ôï óõíèçìáôéêü ëÞãåé:\t"
+
+#: src/chage.c:486
+#, c-format
+msgid "%s: do not include \"l\" with other flags\n"
+msgstr "%s: Íá ìçí óõìðåñéëáìâÜíåôå ôï \"l\" ìå ôéò Üëëåò åíäåßîåéò\n"
+
+#: src/chage.c:498 src/chage.c:610 src/login.c:529
+#, c-format
+msgid "%s: permission denied\n"
+msgstr "%s: Üäåéá áðïññßöèçêå\n"
+
+#: src/chage.c:510 src/chpasswd.c:120
+#, c-format
+msgid "%s: can't lock password file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/chage.c:516 src/chpasswd.c:124
+#, c-format
+msgid "%s: can't open password file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/chage.c:523
+#, c-format
+msgid "%s: unknown user: %s\n"
+msgstr "%s: Üãíùóôïò ÷ñÞóôçò: %s\n"
+
+#: src/chage.c:542
+#, c-format
+msgid "%s: can't lock shadow password file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chage.c:549
+#, c-format
+msgid "%s: can't open shadow password file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chage.c:631
+#, c-format
+msgid "Changing the aging information for %s\n"
+msgstr "ÁëëáãÞ ðëçñïöïñéþí ÷ñüíïõ ãéá ôïí %s\n"
+
+#: src/chage.c:633
+#, c-format
+msgid "%s: error changing fields\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí áëëáãÞ ðåäßùí\n"
+
+#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183
+#, c-format
+msgid "%s: can't update password file\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/chage.c:690 src/pwunconv.c:178
+#, c-format
+msgid "%s: can't update shadow password file\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409
+#: src/passwd.c:825 src/passwd.c:926
+msgid "Error updating the DBM password entry.\n"
+msgstr ""
+"ÓöÜëìá êáôÜ ôçí áíáíÝùóç ôçò êáôá÷þñçóçò óôï dbm áñ÷åßï óõíèçìáôéêþí.\n"
+
+#: src/chage.c:771
+#, c-format
+msgid "%s: can't rewrite shadow password file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chage.c:785
+#, c-format
+msgid "%s: can't rewrite password file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/chage.c:836
+#, c-format
+msgid "%s: no aging information present\n"
+msgstr "%s: Äåí õðÜñ÷ïõí ðëçñïöïñßåò ãÞñáíóçò\n"
+
+#: src/chfn.c:107
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n"
+"\t[ -h home_ph ] [ -o other ] [ user ]\n"
+msgstr ""
+"Usage: %s [ -f ðëÞñåò_üíïìá ] [ -r áñßèì_äùìáôßïõ ] [ -w ôçë_åñãáóßáò ]\n"
+"\t[ -h ôçë_ïéêßáò ] [ -o Üëëï ] [ ÷ñÞóôçò ]\n"
+
+#: src/chfn.c:111
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"
+msgstr ""
+"×ñÞóç: %s [ -f ðëÞñåò_üíïìá ] [ -r áñéèì_äùìáôßïõ ] [ -w ôçë_äùìáôßïõ ]\n"
+"[ -h ôçë_ïéêßáò ]\n"
+
+#: src/chfn.c:163 src/chsh.c:119
+msgid "Enter the new value, or press return for the default\n"
+msgstr "ÅéóÜãåôå ôçí íÝá ôéìÞ, Þ ðéÝóôå `return' ãéá ôçí ðñïêáèïñéóìÝíç\n"
+
+#: src/chfn.c:166
+msgid "Full Name"
+msgstr "ÐëÞñåò üíïìá"
+
+#: src/chfn.c:168
+#, c-format
+msgid "\tFull Name: %s\n"
+msgstr "\tÐëÞñåò ¼íïìá: %s\n"
+
+#: src/chfn.c:171
+msgid "Room Number"
+msgstr "Áñéèìüò äùìáôßïõ"
+
+#: src/chfn.c:173
+#, c-format
+msgid "\tRoom Number: %s\n"
+msgstr "\tÁñéèìüò Äùìáôßïõ: %s\n"
+
+#: src/chfn.c:176
+msgid "Work Phone"
+msgstr "ÔçëÝöùíï Åñãáóßáò"
+
+#: src/chfn.c:178
+#, c-format
+msgid "\tWork Phone: %s\n"
+msgstr "\tÔçëÝöùíï Åñãáóßáò: %s\n"
+
+#: src/chfn.c:181
+msgid "Home Phone"
+msgstr "ÔçëÝöùíï Ïéêßáò"
+
+#: src/chfn.c:183
+#, c-format
+msgid "\tHome Phone: %s\n"
+msgstr "\tÔçëÝöùíï ïéêßáò: %s\n"
+
+#: src/chfn.c:186
+msgid "Other"
+msgstr "Áëëï"
+
+#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330
+#: src/chfn.c:391 src/passwd.c:1226
+#, c-format
+msgid "%s: Permission denied.\n"
+msgstr "%s: ¶äåéá áðïññßöèçêå.\n"
+
+#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277
+#, c-format
+msgid "%s: Unknown user %s\n"
+msgstr "%s: Áãíùóôïò ï ÷ñÞóôçò %s\n"
+
+#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207
+#, c-format
+msgid "%s: Cannot determine your user name.\n"
+msgstr "%s: Äåí åßíáé äõíáôüí íá êáèïñéóôåß ôï üíïìá ÷ñÞóôç óáò.\n"
+
+#: src/chfn.c:373 src/chsh.c:250
+#, c-format
+msgid "%s: cannot change user `%s' on NIS client.\n"
+msgstr "%s: áäõíáìßá áëëáãÞò ÷ñÞóôç `%s' óôïí NIS åîõðçñåôïýìåíï.\n"
+
+#: src/chfn.c:378 src/chsh.c:257
+#, c-format
+msgid "%s: `%s' is the NIS master for this client.\n"
+msgstr "%s: `%s' åßíáé ï êýñéïò äéáêïìéóôÞò NIS ãé'áõôüí ôïí åîõðçñåôïýìåíï.\n"
+
+#: src/chfn.c:453
+#, c-format
+msgid "Changing the user information for %s\n"
+msgstr "ÁëëáãÞ ðëçñïöïñéþí ÷ñÞóôç ãéá ôïí %s\n"
+
+#: src/chfn.c:462
+#, c-format
+msgid "%s: invalid name: \"%s\"\n"
+msgstr "%s: Ìç Ýãêõñï üíïìá: `%s'\n"
+
+#: src/chfn.c:467
+#, c-format
+msgid "%s: invalid room number: \"%s\"\n"
+msgstr "%s: Ìç Ýãêõñïò áñéèìüò äùìáôßïõ: `%s'\n"
+
+#: src/chfn.c:472
+#, c-format
+msgid "%s: invalid work phone: \"%s\"\n"
+msgstr "%s: Ìç Ýãêõñï ôçëÝöùíï åñãáóßáò: `%s'\n"
+
+#: src/chfn.c:477
+#, c-format
+msgid "%s: invalid home phone: \"%s\"\n"
+msgstr "%s: Ìç Ýãêõñï ôçëÝöùíï ïéêßáò: `%s'\n"
+
+#: src/chfn.c:482
+#, c-format
+msgid "%s: \"%s\" contains illegal characters\n"
+msgstr "%s: \"%s\" ðåñéÝ÷åé ìç Ýãêõñïõò ÷áñáêôÞñåò\n"
+
+#: src/chfn.c:494
+#, c-format
+msgid "%s: fields too long\n"
+msgstr "%s: Ðïëý ìáêñéÜ ðåäßá\n"
+
+#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388
+msgid "Cannot change ID to root.\n"
+msgstr "Áäõíáìßá áëëáãÞò ôáõôüôçôáò ÷ñÞóôç óå root.\n"
+
+#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880
+msgid "Cannot lock the password file; try again later.\n"
+msgstr "Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí. ÄïêéìÜóôå áñãüôåñá.\n"
+
+#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885
+msgid "Cannot open the password file.\n"
+msgstr "Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí.\n"
+
+#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313
+#, c-format
+msgid "%s: %s not found in /etc/passwd\n"
+msgstr "%s: Ï %s äåí âñÝèçêå óôï /etc/passwd\n"
+
+#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920
+#: src/passwd.c:960
+msgid "Error updating the password entry.\n"
+msgstr "ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí.\n"
+
+#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933
+msgid "Cannot commit password file changes.\n"
+msgstr "Áäõíáìßá åéóáãùãÞò ôùí áëëáãþí óôï áñ÷åßï óõíèçìáôéêþí.\n"
+
+#: src/chfn.c:592 src/chsh.c:431
+msgid "Cannot unlock the password file.\n"
+msgstr "Áäõíáìßá îåêëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/chpasswd.c:76
+#, c-format
+msgid "usage: %s [-e]\n"
+msgstr "÷ñÞóç: %s [-e]\n"
+
+#: src/chpasswd.c:132 src/pwconv.c:104
+#, c-format
+msgid "%s: can't lock shadow file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118
+#: src/pwunconv.c:123
+#, c-format
+msgid "%s: can't open shadow file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chpasswd.c:159 src/newusers.c:415
+#, c-format
+msgid "%s: line %d: line too long\n"
+msgstr "%s: ãñáììÞ %d: ðïëý ìåãÜëç ãñáììÞ\n"
+
+#: src/chpasswd.c:179
+#, c-format
+msgid "%s: line %d: missing new password\n"
+msgstr "%s: ãñáììÞ %d: Ýëëåéøç íÝïõ óõíèçìáôéêïý\n"
+
+#: src/chpasswd.c:195
+#, c-format
+msgid "%s: line %d: unknown user %s\n"
+msgstr "%s: ãñáììÞ %d: Üãíùóôïò ÷ñÞóôçò %s\n"
+
+#: src/chpasswd.c:247
+#, c-format
+msgid "%s: line %d: cannot update password entry\n"
+msgstr "%s: ãñáììÞ %d: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óõíèçìáôéêïý\n"
+
+#: src/chpasswd.c:263 src/newusers.c:535
+#, c-format
+msgid "%s: error detected, changes ignored\n"
+msgstr "%s: Áíé÷íÝõôçêå óöÜëìá, ïé áëëáãÝò áãíïÞèçêáí\n"
+
+#: src/chpasswd.c:274
+#, c-format
+msgid "%s: error updating shadow file\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/chpasswd.c:282
+#, c-format
+msgid "%s: error updating password file\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/chsh.c:105
+#, c-format
+msgid "Usage: %s [ -s shell ] [ name ]\n"
+msgstr "×ñÞóç: %s [ -s öëïéüò ] [ üíïìá ]\n"
+
+#: src/chsh.c:120
+msgid "Login Shell"
+msgstr "ÊÝëõöïò Åéóüäïõ"
+
+#: src/chsh.c:273 src/chsh.c:286
+#, c-format
+msgid "You may not change the shell for %s.\n"
+msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôï öëïéü ãéá ôï(í) %s.\n"
+
+#: src/chsh.c:315
+#, c-format
+msgid "Changing the login shell for %s\n"
+msgstr "ÁëëÜãÞ ôïõ öëïéïý ãéá ôïí %s\n"
+
+#: src/chsh.c:327
+#, c-format
+msgid "%s: Invalid entry: %s\n"
+msgstr "%s: Ìç Ýãêõñç êáôá÷þñçóç: %s\n"
+
+#: src/chsh.c:332
+#, c-format
+msgid "%s is an invalid shell.\n"
+msgstr "%s äåí åßíáé Ýãêõñïò öëïéüò.\n"
+
+#: src/dpasswd.c:69
+#, c-format
+msgid "Usage: %s [ -(a|d) ] shell\n"
+msgstr "×ñÞóç: %s [ -(ald) ] öëïéüò\n"
+
+#: src/dpasswd.c:134
+msgid "Shell password: "
+msgstr "Óõíèçìáôéêü öëïéïý: "
+
+#: src/dpasswd.c:140
+msgid "re-enter Shell password: "
+msgstr "ÅðáíåéóÜãåôå ôï óõíèçìáôéêü öëïéïý: "
+
+#: src/dpasswd.c:147
+#, c-format
+msgid "%s: Passwords do not match, try again.\n"
+msgstr "%s: Ôá óõíèçìáôéêÜ äåí ôáéñéÜæïõí, äïêéìÜóôå îáíÜ.\n"
+
+#: src/dpasswd.c:167
+#, c-format
+msgid "%s: can't create %s"
+msgstr "%s: áäõíáìßá äçìéïõñãßáò ôïõ %s"
+
+#: src/dpasswd.c:172
+#, c-format
+msgid "%s: can't open %s"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ %s"
+
+#: src/dpasswd.c:200
+#, c-format
+msgid "%s: Shell %s not found.\n"
+msgstr "%s: Ï öëïéüò %s äåí âñÝèçêå.\n"
+
+#: src/expiry.c:84
+msgid "Usage: expiry { -f | -c }\n"
+msgstr "×ñÞóç: expiry { -f | -c }\n"
+
+#: src/expiry.c:137
+#, c-format
+msgid "%s: WARNING! Must be set-UID root!\n"
+msgstr ""
+"%s: ÐÑÏÓÏ×Ç! ÐñÝðåé íá Ý÷åé ôåèåß ôï bit ðáñá÷þñçóçò ôáõôüôçôáò root!\n"
+
+#: src/expiry.c:148
+#, c-format
+msgid "%s: unknown user\n"
+msgstr "%s: Üãíùóôïò ÷ñÞóôçò\n"
+
+#: src/faillog.c:79
+#, c-format
+msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"
+msgstr ""
+"÷ñÞóç: %s [-a|-u ÷ñÞóôçò] [-m ìåã] [-r] [-t ìÝñåò] [-l äåõôåñüëåðôá_êëåéä]\n"
+
+#: src/faillog.c:134 src/lastlog.c:94
+#, c-format
+msgid "Unknown User: %s\n"
+msgstr "Áãíùóôïò ÷ñÞóôçò: %s\n"
+
+#: src/faillog.c:215
+msgid "Username Failures Maximum Latest\n"
+msgstr "¼íïìá_×ñÞóôç Áðïôõ÷ßåò ÌÝãéóôï Ôåëåõôáßá\n"
+
+#: src/faillog.c:232
+#, c-format
+msgid " %s on %s"
+msgstr " %s óôï %s"
+
+#: src/faillog.c:236
+#, c-format
+msgid " [%lds left]"
+msgstr " [%lds áðÝìåéíáí]"
+
+#: src/faillog.c:239
+#, c-format
+msgid " [%lds lock]"
+msgstr " [%lds êëåßäùìá]"
+
+#: src/gpasswd.c:89
+#, c-format
+msgid "usage: %s [-r|-R] group\n"
+msgstr "÷ñÞóç: %s [-r|-R] ïìÜäá\n"
+
+#: src/gpasswd.c:90
+#, c-format
+msgid " %s [-a user] group\n"
+msgstr " %s [-a ÷ñÞóôçò] ïìÜäá\n"
+
+#: src/gpasswd.c:91
+#, c-format
+msgid " %s [-d user] group\n"
+msgstr " %s [-d ÷ñÞóôçò] ïìÜäá\n"
+
+#: src/gpasswd.c:93
+#, c-format
+msgid " %s [-A user,...] [-M user,...] group\n"
+msgstr " %s [-A ÷ñÞóôçò,...] [-M ÷ñÞóôçò,...] ïìÜäá\n"
+
+#: src/gpasswd.c:96
+#, c-format
+msgid " %s [-M user,...] group\n"
+msgstr " %s [-M ÷ñÞóôçò,...] ïìÜäá\n"
+
+#: src/gpasswd.c:160 src/gpasswd.c:245
+#, c-format
+msgid "%s: unknown user %s\n"
+msgstr "%s: Üãíùóôïò ÷ñÞóôçò %s\n"
+
+#: src/gpasswd.c:172
+msgid "Permission denied.\n"
+msgstr "¶äåéá áðïññßöèçêå.\n"
+
+#: src/gpasswd.c:257
+#, c-format
+msgid "%s: shadow group passwords required for -A\n"
+msgstr "%s: óêéþäç óõíèçìáôéêÜ ïìÜäùí áðáéôïýíôáé ãéá ôï -A\n"
+
+#: src/gpasswd.c:308
+msgid "Who are you?\n"
+msgstr "Ðïéïò åßóáé;\n"
+
+#: src/gpasswd.c:328 src/newgrp.c:251
+#, c-format
+msgid "unknown group: %s\n"
+msgstr "Üãíùóôç ïìÜäá: %s\n"
+
+#: src/gpasswd.c:436
+#, c-format
+msgid "Adding user %s to group %s\n"
+msgstr "ÐñïóèÞêç ôïõ ÷ñÞóôç %s óôçí ïìÜäá %s\n"
+
+#: src/gpasswd.c:453
+#, c-format
+msgid "Removing user %s from group %s\n"
+msgstr "ÄéáãñÜöç ôïõ ÷ñÞóôç %s áðü ôçí ïìÜäá %s\n"
+
+#: src/gpasswd.c:466
+#, c-format
+msgid "%s: unknown member %s\n"
+msgstr "%s: Üãíùóôï ìÝëïò %s\n"
+
+#: src/gpasswd.c:513
+#, c-format
+msgid "%s: Not a tty\n"
+msgstr "%s: Äåí åßíáé tty\n"
+
+#.
+#. * A new password is to be entered and it must be encrypted,
+#. * etc. The password will be prompted for twice, and both
+#. * entries must be identical. There is no need to validate
+#. * the old password since the invoker is either the group
+#. * owner, or root.
+#.
+#: src/gpasswd.c:535
+#, c-format
+msgid "Changing the password for group %s\n"
+msgstr "ÁëëáãÞ ôïõ óõíèÞìáôïò ãéá ôçí ïìÜäá %s\n"
+
+#: src/gpasswd.c:538
+msgid "New Password: "
+msgstr "ÍÝï Óõíèçìáôéêü: "
+
+#: src/gpasswd.c:543 src/passwd.c:422
+msgid "Re-enter new password: "
+msgstr "ÅðáíåéóÜãåôå ôï íÝï óõíèçìáôéêü: "
+
+#: src/gpasswd.c:555
+msgid "They don't match; try again"
+msgstr "Äåí ôáéñéÜæïõí. ÄïêéìÜóôå îáíÜ"
+
+#: src/gpasswd.c:559
+#, c-format
+msgid "%s: Try again later\n"
+msgstr "%s: ÎáíáäïêéìÜóôå áñãüôåñá\n"
+
+#: src/gpasswd.c:590
+#, c-format
+msgid "%s: can't get lock\n"
+msgstr "%s: Áäõíáìßá äçìéïõñãßáò êëåéäþìáôïò\n"
+
+#: src/gpasswd.c:596
+#, c-format
+msgid "%s: can't get shadow lock\n"
+msgstr ""
+"%s: Áäõíáìßá äçìéïõñãßáò êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/gpasswd.c:602
+#, c-format
+msgid "%s: can't open file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ %s\n"
+
+#: src/gpasswd.c:614
+#, c-format
+msgid "%s: can't update entry\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò\n"
+
+#: src/gpasswd.c:620
+#, c-format
+msgid "%s: can't update shadow entry\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/gpasswd.c:626
+#, c-format
+msgid "%s: can't re-write file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ\n"
+
+#: src/gpasswd.c:632
+#, c-format
+msgid "%s: can't re-write shadow file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/gpasswd.c:640
+#, c-format
+msgid "%s: can't unlock file\n"
+msgstr "%s: áäõíáìßá îåêëåéäþìáôïò áñ÷åßïõ\n"
+
+#: src/gpasswd.c:645
+#, c-format
+msgid "%s: can't update DBM files\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ôùí DBM áñ÷åßùí\n"
+
+#: src/gpasswd.c:652
+#, c-format
+msgid "%s: can't update DBM shadow files\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ôùí DBM áñ÷åßùí óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/groupadd.c:105
+msgid "usage: groupadd [-g gid [-o]] group\n"
+msgstr "÷ñÞóç: groupadd [-g gid [-o]] ïìÜäá\n"
+
+#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230
+#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675
+#, c-format
+msgid "%s: error adding new group entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n"
+
+#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942
+#: src/usermod.c:551 src/usermod.c:687
+#, c-format
+msgid "%s: cannot add new dbm group entry\n"
+msgstr "%s: áäõíáìßá ðñïóèÞêçò íÝáò dbm êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n"
+
+#: src/groupadd.c:258 src/useradd.c:996
+#, c-format
+msgid "%s: name %s is not unique\n"
+msgstr "%s: Ôï üíïìá %s äåí åßíáé ìïíáäéêü\n"
+
+#: src/groupadd.c:273
+#, c-format
+msgid "%s: gid %ld is not unique\n"
+msgstr "%s: Ôï gid %ld äåí åßíáé ìïíáäéêü\n"
+
+#: src/groupadd.c:297
+#, c-format
+msgid "%s: can't get unique gid\n"
+msgstr "%s: áäõíáìßá åýñåóçò ìïíáäéêïý gid\n"
+
+#.
+#. * All invalid group names land here.
+#.
+#: src/groupadd.c:321 src/groupmod.c:341
+#, c-format
+msgid "%s: %s is a not a valid group name\n"
+msgstr "%s: Ôï %s äåí åßíáé Ýãêõñï üíïìá ïìÜäáò\n"
+
+#: src/groupadd.c:350 src/groupmod.c:367
+#, c-format
+msgid "%s: invalid group %s\n"
+msgstr "%s: Ìç Ýãêõñç ïìÜäá `%s'\n"
+
+#: src/groupadd.c:367 src/useradd.c:1272
+#, c-format
+msgid "%s: -O requires NAME=VALUE\n"
+msgstr "%s: -O áðáéôåß ¼ÍÏÌÁ=ÔÉÌÇ\n"
+
+#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381
+#: src/userdel.c:303 src/usermod.c:563
+#, c-format
+msgid "%s: cannot rewrite group file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389
+#: src/userdel.c:309 src/usermod.c:700
+#, c-format
+msgid "%s: cannot rewrite shadow group file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389
+#, c-format
+msgid "%s: unable to lock group file\n"
+msgstr "%s: Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432
+#, c-format
+msgid "%s: unable to open group file\n"
+msgstr "%s: Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398
+#, c-format
+msgid "%s: unable to lock shadow group file\n"
+msgstr "%s: Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442
+#, c-format
+msgid "%s: unable to open shadow group file\n"
+msgstr "%s: Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/groupadd.c:518
+#, c-format
+msgid "%s: group %s exists\n"
+msgstr "%s: Ç ïìÜäá %s õðÜñ÷åé\n"
+
+#: src/groupdel.c:86
+msgid "usage: groupdel group\n"
+msgstr "÷ñÞóç: groupdel ïìÜäá\n"
+
+#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234
+#, c-format
+msgid "%s: error removing group entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò ïìÜäáò\n"
+
+#: src/groupdel.c:116 src/groupmod.c:206
+#, c-format
+msgid "%s: error removing group dbm entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï dbm áñ÷åßï ïìÜäùí\n"
+
+#: src/groupdel.c:131
+#, c-format
+msgid "%s: error removing shadow group entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí "
+"ïìÜäùí\n"
+
+#: src/groupdel.c:144 src/groupmod.c:252
+#, c-format
+msgid "%s: error removing shadow group dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#.
+#. * Can't remove the group.
+#.
+#: src/groupdel.c:248
+#, c-format
+msgid "%s: cannot remove user's primary group.\n"
+msgstr "%s: áäõíáìßá áöáßñåóçò ôçò ðñùôáñ÷éêÞò ïìÜäáò ôïõ ÷ñÞóôç.\n"
+
+#: src/groupdel.c:305 src/groupmod.c:501
+#, c-format
+msgid "%s: group %s does not exist\n"
+msgstr "%s: Ç ïìÜäá %s äåí õðÜñ÷åé\n"
+
+#: src/groupdel.c:319 src/groupmod.c:517
+#, c-format
+msgid "%s: group %s is a NIS group\n"
+msgstr "%s: Ç ïìÜäá %s åßíáé NIS ïìÜäá\n"
+
+#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016
+#, c-format
+msgid "%s: %s is the NIS master\n"
+msgstr "%s: Ï %s åßíáé ï êýñéïò äéáêïìéóôÞò NIS\n"
+
+#: src/groupmod.c:105
+msgid "usage: groupmod [-g gid [-o]] [-n name] group\n"
+msgstr "÷ñÞóç: groupmod [-g gid [-o]] [-n üíïìá] ïìÜäá\n"
+
+#: src/groupmod.c:165
+#, fuzzy, c-format
+msgid "%s: %s not found in /etc/group\n"
+msgstr "%s: Ï %s äåí âñÝèçêå óôï /etc/passwd\n"
+
+#: src/groupmod.c:246
+#, c-format
+msgid "%s: cannot add new dbm shadow group entry\n"
+msgstr ""
+"%s: áäõíáìßá ðñïóèÞêçò íÝáò dbm êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí "
+"ïìÜäùí\n"
+
+#: src/groupmod.c:299
+#, c-format
+msgid "%s: %ld is not a unique gid\n"
+msgstr "%s: Ôï %ld äåí åßíáé ìïíáäéêü gid\n"
+
+#: src/groupmod.c:330
+#, c-format
+msgid "%s: %s is not a unique name\n"
+msgstr "%s: Ôï %s äåí åßíáé ìïíáäéêü üíïìá\n"
+
+#: src/groups.c:62
+#, c-format
+msgid "unknown user %s\n"
+msgstr "Üãíùóôïò ÷ñÞóôçò: %s\n"
+
+#: src/grpck.c:98
+#, c-format
+msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n"
+msgstr "×ñÞóç: %s [ -r ] [ group [ gshadow ] ]\n"
+
+#: src/grpck.c:100
+#, c-format
+msgid "Usage: %s [ -r ] [ group ]\n"
+msgstr "×ñÞóç: %s [ -r ] [ group ]\n"
+
+#: src/grpck.c:119 src/pwck.c:119
+msgid "No"
+msgstr "Ï÷é"
+
+#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225
+#, c-format
+msgid "%s: cannot lock file %s\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ %s\n"
+
+#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241
+#: src/pwck.c:250
+#, c-format
+msgid "%s: cannot open file %s\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ %s\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:298
+msgid "invalid group file entry\n"
+msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï ïìÜäùí\n"
+
+#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517
+#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517
+#: src/pwck.c:541
+#, c-format
+msgid "delete line `%s'? "
+msgstr "äéáãñáöÞ ãñáììÞò `%s'; "
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:361
+msgid "duplicate group entry\n"
+msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n"
+
+#: src/grpck.c:378
+#, c-format
+msgid "invalid group name `%s'\n"
+msgstr "Ìç Ýãêõñï üíïìá ïìÜäáò `%s'\n"
+
+#: src/grpck.c:388
+#, c-format
+msgid "group %s: bad GID (%d)\n"
+msgstr "ïìÜäá %s: ëÜèïò GID (%d)\n"
+
+#: src/grpck.c:414
+#, c-format
+msgid "group %s: no user %s\n"
+msgstr "ïìÜäá %s: äåí õðÜñ÷åé ÷ñÞóôçò %s\n"
+
+#: src/grpck.c:416 src/grpck.c:585
+#, c-format
+msgid "delete member `%s'? "
+msgstr "äéáãñáöÞ ìÝëïõò `%s'; "
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:453
+msgid "invalid shadow group file entry\n"
+msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:516
+msgid "duplicate shadow group entry\n"
+msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/grpck.c:533
+msgid "no matching group file entry\n"
+msgstr "Äåí âñÝèçêå êáôá÷þñçóç óôï áñ÷åßï ïìÜäùí ðïõ íá ôáéñéÜæåé\n"
+
+#: src/grpck.c:553
+#, c-format
+msgid "shadow group %s: no administrative user %s\n"
+msgstr "óêéþäçò ïìÜäá %s: Äåí õðÜñ÷åé äéá÷åéñéóôÞò ÷ñÞóôçò %s\n"
+
+#: src/grpck.c:555
+#, c-format
+msgid "delete administrative member `%s'? "
+msgstr "äéáãñáöÞ äéá÷åéñéóôéêïý ìÝëïõò `%s'; "
+
+#: src/grpck.c:583
+#, c-format
+msgid "shadow group %s: no user %s\n"
+msgstr "óêéþäçò ïìÜäá %s: äåí õðÜñ÷åé ÷ñÞóôçò %s\n"
+
+#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580
+#, c-format
+msgid "%s: cannot update file %s\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò áñ÷åßïõ %s\n"
+
+#: src/grpck.c:640 src/pwck.c:606
+#, c-format
+msgid "%s: the files have been updated; run mkpasswd\n"
+msgstr "%s: ôá áñ÷åßá áíáíåþèçêáí. ÅêôåëÝóôå mkpasswd\n"
+
+#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611
+#, c-format
+msgid "%s: no changes\n"
+msgstr "%s: êáìéÜ áëëáãÞ\n"
+
+#: src/grpck.c:644 src/pwck.c:610
+#, c-format
+msgid "%s: the files have been updated\n"
+msgstr "%s: ôá áñ÷åßá áíáíåþèçêáí\n"
+
+#: src/grpconv.c:62 src/grpunconv.c:63
+#, c-format
+msgid "%s: can't lock group file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/grpconv.c:67 src/grpunconv.c:68
+#, c-format
+msgid "%s: can't open group file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/grpconv.c:72 src/grpunconv.c:73
+#, c-format
+msgid "%s: can't lock shadow group file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/grpconv.c:77 src/grpunconv.c:78
+#, c-format
+msgid "%s: can't open shadow group file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#.
+#. * This shouldn't happen (the entry exists) but...
+#.
+#: src/grpconv.c:93
+#, c-format
+msgid "%s: can't remove shadow group %s\n"
+msgstr ""
+"%s: áäõíáìßá áöáßñåóçò ôçò ïìÜäáò %s, áðü ôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+"ïìÜäùí\n"
+
+#: src/grpconv.c:134 src/pwconv.c:160
+#, c-format
+msgid "%s: can't update shadow entry for %s\n"
+msgstr ""
+"%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ãéá ôïí "
+"%s\n"
+
+#: src/grpconv.c:143 src/grpunconv.c:94
+#, c-format
+msgid "%s: can't update entry for group %s\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò ãéá ôçí ïìÜäá %s\n"
+
+#: src/grpconv.c:150 src/grpunconv.c:102
+#, c-format
+msgid "%s: can't update shadow group file\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/grpconv.c:154 src/grpunconv.c:107
+#, c-format
+msgid "%s: can't update group file\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ãéá ôï áñ÷åßï ïìÜäùí\n"
+
+#: src/grpconv.c:169 src/grpunconv.c:128
+#, c-format
+msgid "%s: not configured for shadow group support.\n"
+msgstr "%s: Äåí åßíáé äéáìïñöùìÝíï ãéá óêéþäç óõíèçìáôéêÜ ïìÜäùí.\n"
+
+#: src/grpunconv.c:112
+#, c-format
+msgid "%s: can't delete shadow group file\n"
+msgstr ""
+"%s: Äåí åßíáé äõíáôüí íá äéáãñáöåß ôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/id.c:56
+msgid "usage: id [ -a ]\n"
+msgstr "÷ñÞóç: id [ -a ]\n"
+
+#: src/id.c:58
+msgid "usage: id\n"
+msgstr "÷ñÞóç: id\n"
+
+#: src/id.c:118
+#, c-format
+msgid "uid=%d(%s)"
+msgstr ""
+
+#: src/id.c:120
+#, c-format
+msgid "uid=%d"
+msgstr ""
+
+#: src/id.c:124
+#, c-format
+msgid " gid=%d(%s)"
+msgstr ""
+
+#: src/id.c:126
+#, c-format
+msgid " gid=%d"
+msgstr ""
+
+#: src/id.c:136
+#, c-format
+msgid " euid=%d(%s)"
+msgstr ""
+
+#: src/id.c:138
+#, c-format
+msgid " euid=%d"
+msgstr ""
+
+#: src/id.c:143
+#, c-format
+msgid " egid=%d(%s)"
+msgstr ""
+
+#: src/id.c:145
+#, c-format
+msgid " egid=%d"
+msgstr ""
+
+#.
+#. * Start off the group message. It will be of the format
+#. *
+#. * groups=###(aaa),###(aaa),###(aaa)
+#. *
+#. * where "###" is a numerical value and "aaa" is the
+#. * corresponding name for each respective numerical value.
+#.
+#: src/id.c:166
+msgid " groups="
+msgstr " ïìÜäåò="
+
+#: src/lastlog.c:167
+msgid "Username Port From Latest\n"
+msgstr "¼íïìá_×ñÞóôç Èýñá Áðü Ôåëåõôáßá\n"
+
+#: src/lastlog.c:169
+msgid "Username Port Latest\n"
+msgstr "¼íïìá_×ñÞóôç Èýñá Ôåëåõôáßá\n"
+
+#: src/lastlog.c:183
+msgid "**Never logged in**"
+msgstr "**ÊáìéÜ åßóïäïò óôï óýóôçìá**"
+
+#: src/login.c:198
+#, c-format
+msgid "usage: %s [-p] [name]\n"
+msgstr "÷ñÞóç: %s [-p] [üíïìá]\n"
+
+#: src/login.c:201
+#, c-format
+msgid " %s [-p] [-h host] [-f name]\n"
+msgstr " %s [-p] [-h óýóôçìá] [-f üíïìá]\n"
+
+#: src/login.c:203
+#, c-format
+msgid " %s [-p] -r host\n"
+msgstr " %s [-p] -r óýóôçìá\n"
+
+#: src/login.c:286
+msgid "Invalid login time\n"
+msgstr "ÅóöáëìÝíç þñá åéóüäïõ\n"
+
+#: src/login.c:341
+msgid ""
+"\n"
+"System closed for routine maintenance\n"
+msgstr ""
+"\n"
+"Ôï óýóôçìá Ýêëåéóå ãéá óõíôÞñçóç ñïõôßíáò\n"
+
+#: src/login.c:351
+msgid ""
+"\n"
+"[Disconnect bypassed -- root login allowed.]\n"
+msgstr ""
+"\n"
+"[ÐáñÜêáìøç áðïóýíäåóçò -- Ç åßóïäïò ôïõ root åðåôñÜðç.]\n"
+
+#: src/login.c:390
+#, c-format
+msgid ""
+"\n"
+"Login timed out after %d seconds.\n"
+msgstr ""
+"\n"
+"Ç äéáäéêáóßá åéóüäïõ ôåñìáôßóôçêå ìåôÜ áðü %d äåõôåñüëåðôá.\n"
+
+#: src/login.c:692
+#, c-format
+msgid " on `%.100s' from `%.200s'"
+msgstr " óôï `%.100s' áðü `%.200s'"
+
+#: src/login.c:694
+#, c-format
+msgid " on `%.100s'"
+msgstr " óôï `%.100s'"
+
+#: src/login.c:834
+#, c-format
+msgid ""
+"\n"
+"%s login: "
+msgstr ""
+"\n"
+"%s login: "
+
+#: src/login.c:836
+msgid "login: "
+msgstr "login: "
+
+#: src/login.c:1026 src/sulogin.c:231
+msgid "Login incorrect"
+msgstr "Äéáäéêáóßá åéóüäïõ áðÝôõ÷å"
+
+#: src/login.c:1213
+msgid "Warning: login re-enabled after temporary lockout.\n"
+msgstr ""
+"Ðñïåéäïðïßçóç: Ç åßóïäïò åðáíåíåñãïðïéÞèçêå ìåôÜ áðü ðñïóùñéíü áðïêëåéóìü.\n"
+
+#: src/login.c:1223
+#, c-format
+msgid "Last login: %s on %s"
+msgstr "Ôåëåõôáßá åßóïäïò: %s óôï %s"
+
+#: src/login.c:1226
+#, c-format
+msgid "Last login: %.19s on %s"
+msgstr "Ôåëåõôáßá åßóïäïò: %.19s óôï %s"
+
+#: src/login.c:1231
+#, c-format
+msgid " from %.*s"
+msgstr " áðü %.*s"
+
+#: src/login.c:1303
+msgid "Starting rad_login\n"
+msgstr "¸íáñîç rad_login\n"
+
+#: src/mkpasswd.c:49
+#, c-format
+msgid "%s: no DBM database on system - no action performed\n"
+msgstr ""
+"%s: Äåí õðÜñ÷åé DBM âÜóç äåäïìÝíùí óôï óýóôçìá - êáìéÜ åíÝñãåéá äåí "
+"åêôåëåßôáé\n"
+
+#: src/mkpasswd.c:245 src/mkpasswd.c:249
+#, c-format
+msgid "%s: cannot overwrite file %s\n"
+msgstr "%s: áäõíáìßá åããñáöÞò ðÜíù áðü ôï áñ÷åßï %s\n"
+
+#: src/mkpasswd.c:263
+#, c-format
+msgid "%s: cannot open DBM files for %s\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò DBM áñ÷åßùí ãéá ôï %s\n"
+
+#: src/mkpasswd.c:296
+#, c-format
+msgid "%s: the beginning with "
+msgstr "%s: ç áñ÷Þ ìå "
+
+#: src/mkpasswd.c:321
+#, c-format
+msgid "%s: error parsing line \"%s\"\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí åðåîåñãáóßá ôçò ãñáììÞò \"%s\"\n"
+
+#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332
+msgid "adding record for name "
+msgstr "ðñïóèÞêç êáôá÷þñçóçò ãéá üíïìá "
+
+#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349
+#, c-format
+msgid "%s: error adding record for "
+msgstr "%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç êáôá÷þñçóçò ãéá "
+
+#: src/mkpasswd.c:367
+#, c-format
+msgid "added %d entries, longest was %d\n"
+msgstr "ðñïóôÝèçêáí %d êáôá÷ùñÞóåéò, ç ìåãáëýôåñç Þôáí %d\n"
+
+#: src/mkpasswd.c:382
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"
+msgstr "×ñÞóç: %s [ -vf ] [ -p|g|sp|sg ] áñ÷åßï\n"
+
+#: src/mkpasswd.c:384
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n"
+msgstr "×ñÞóç: %s [ -vf ] [ -p|g|sp ] áñ÷åßï\n"
+
+#: src/mkpasswd.c:387
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g ] file\n"
+msgstr "×ñÞóç: %s [ -vf ] [ -p|g ] áñ÷åßï\n"
+
+#: src/newgrp.c:66
+msgid "usage: newgrp [ - ] [ group ]\n"
+msgstr "÷ñÞóç: newgrp [ - ] [ ïìÜäá ]\n"
+
+#: src/newgrp.c:68
+#, fuzzy
+msgid "usage: sg group [[-c] command ]\n"
+msgstr "÷ñÞóç: sg ïìÜäá [ åíôïëÞ ]\n"
+
+#: src/newgrp.c:125
+#, c-format
+msgid "unknown uid: %d\n"
+msgstr "Üãíùóôï uid: %d\n"
+
+#: src/newgrp.c:201
+#, c-format
+msgid "unknown gid: %ld\n"
+msgstr "Üãíùóôï gid: %ld\n"
+
+#: src/newgrp.c:245
+#, c-format
+msgid "unknown gid: %d\n"
+msgstr "Üãíùóôï gid: %d\n"
+
+#: src/newgrp.c:323 src/newgrp.c:332
+msgid "Sorry.\n"
+msgstr "ËõðÜìáé.\n"
+
+#: src/newgrp.c:364
+msgid "too many groups\n"
+msgstr "ðÜñá ðïëëÝò ïìÜäåò\n"
+
+#: src/newusers.c:76
+#, c-format
+msgid "Usage: %s [ input ]\n"
+msgstr "×ñÞóç: %s [ åßóïäïò ]\n"
+
+#: src/newusers.c:364
+#, c-format
+msgid "%s: can't lock /etc/passwd.\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ /etc/passwd.\n"
+
+#: src/newusers.c:375
+#, c-format
+msgid "%s: can't lock files, try again later\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò áñ÷åßùí, îáíáäïêéìÜóôå áñãüôåñá\n"
+
+#: src/newusers.c:390
+#, c-format
+msgid "%s: can't open files\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôùí áñ÷åßùí\n"
+
+#: src/newusers.c:435
+#, c-format
+msgid "%s: line %d: invalid line\n"
+msgstr "%s: ãñáììÞ %d: ìç Ýãêõñç ãñáììÞ\n"
+
+#: src/newusers.c:453
+#, c-format
+msgid "%s: line %d: can't create GID\n"
+msgstr "%s: ãñáììÞ %d: áäõíáìßá äçìéïõñãßáò GID\n"
+
+#: src/newusers.c:469
+#, c-format
+msgid "%s: line %d: can't create UID\n"
+msgstr "%s: ãñáììÞ %d: áäõíáìßá äçìéïõñãßáò UID\n"
+
+#: src/newusers.c:481
+#, c-format
+msgid "%s: line %d: cannot find user %s\n"
+msgstr "%s: ãñáììÞ %d: áäõíáìßá åýñåóçò ÷ñÞóôç %s\n"
+
+#: src/newusers.c:489
+#, c-format
+msgid "%s: line %d: can't update password\n"
+msgstr "%s: ãñáììÞ %d: áäõíáìßá áíáíÝùóç óõíèçìáôéêïý\n"
+
+#: src/newusers.c:506
+#, c-format
+msgid "%s: line %d: mkdir failed\n"
+msgstr "%s: ãñáììÞ %d: áðïôõ÷ßá äçìéïõñãßáò êáôáëüãïõ(mkdir)\n"
+
+#: src/newusers.c:510
+#, c-format
+msgid "%s: line %d: chown failed\n"
+msgstr "%s: ãñáììÞ %d: áðïôõ÷ßá áëëáãÞò éäéïêôÞôç(chown)\n"
+
+#: src/newusers.c:519
+#, c-format
+msgid "%s: line %d: can't update entry\n"
+msgstr "%s: ãñáììÞ %d: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò\n"
+
+#: src/newusers.c:550
+#, c-format
+msgid "%s: error updating files\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí åíçìÝñùóç áñ÷åßùí\n"
+
+#: src/passwd.c:239
+#, c-format
+msgid "usage: %s [ -f | -s ] [ name ]\n"
+msgstr "÷ñÞóç: %s [ -f | -s ] [ üíïìá ]\n"
+
+#: src/passwd.c:242
+#, c-format
+msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"
+msgstr ""
+" %s [ -x ìåã. ] [ -n åëÜ÷. ] [ -w ðñïåéä. ] [ -i áíåíåñãü ] üíïìá\n"
+
+#: src/passwd.c:245
+#, c-format
+msgid " %s { -l | -u | -d | -S | -e } name\n"
+msgstr " %s { -l | -u | -d | -S | -e } üíïìá\n"
+
+#: src/passwd.c:347
+#, c-format
+msgid "User %s has a TCFS key, his old password is required.\n"
+msgstr "Ï ÷ñÞóôçò %s Ý÷åé êëåéäß TCFS, áðáéôåßôáé ôï ðáëéü óõíèçìáôéêü.\n"
+
+#: src/passwd.c:348
+msgid "You can use -t option to force the change.\n"
+msgstr ""
+"Ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ôçí -t ðáñÜìåôñï ãéá íá åîáíáãêÜóåôå ôçí\n"
+"ðñáãìáôïðïßçóç ôçò áëëáãÞò.\n"
+
+#: src/passwd.c:354
+msgid "Old password: "
+msgstr "Ðáëéü Óõíèçìáôéêü: "
+
+#: src/passwd.c:361
+#, c-format
+msgid "Incorrect password for `%s'\n"
+msgstr "ÅóöáëìÝíï óõíèçìáôéêü ãéá ôïí `%s'\n"
+
+#: src/passwd.c:374
+#, c-format
+msgid "Warning: user %s has a TCFS key.\n"
+msgstr "Ðñïåéäïðïßçóç: Ï ÷ñÞóôçò %s Ý÷åé êëåéäß TCFS.\n"
+
+#: src/passwd.c:392
+#, c-format
+msgid ""
+"Enter the new password (minimum of %d, maximum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"
+msgstr ""
+"ÅéóÜãåôå ôï íÝï óõíèçìáôéêü (åëÜ÷éóôï %d, ìÝãéóôï %d ÷áñáêôÞñåò)\n"
+"Ðáñáêáëþ ÷ñçóéìïðïéÞóôå Ýíá óõíäõáóìü áðü êåöáëáßá êáé ìéêñÜ ãñÜììáôá\n"
+"êáèþò êáé áñéèìïýò.\n"
+
+#: src/passwd.c:399
+msgid "New password: "
+msgstr "ÍÝï Óõíèçìáôéêü: "
+
+#: src/passwd.c:409
+msgid "Try again.\n"
+msgstr "ÎáíáäïêéìÜóôå.\n"
+
+#: src/passwd.c:418
+msgid ""
+"\n"
+"Warning: weak password (enter it again to use it anyway).\n"
+msgstr ""
+"\n"
+"Ðñïóï÷Þ: áäýíáìï óõíèçìáôéêü (åéóÜãåôÝ ôï ðÜëé ãéá íá ôï ÷ñçóéìïðïéÞóåôå).\n"
+
+#: src/passwd.c:427
+msgid "They don't match; try again.\n"
+msgstr "Äåí ôáéñéÜæïõí. ÄïêéìÜóôå îáíÜ.\n"
+
+#: src/passwd.c:512 src/passwd.c:528
+#, c-format
+msgid "The password for %s cannot be changed.\n"
+msgstr "Ôï óõíèçìáôéêü ãéá ôïí %s äåí ìðïñåß íá áëëÜîåé.\n"
+
+#: src/passwd.c:556
+#, c-format
+msgid "Sorry, the password for %s cannot be changed yet.\n"
+msgstr "Óõãíþìç, ôï óõíèçìáôéêü ãéá ôïí %s äåí ìðïñåß íá áëëÜîåé áêüìç.\n"
+
+#: src/passwd.c:693
+#, c-format
+msgid "%s: out of memory\n"
+msgstr "%s: äåí õðÜñ÷åé åëåýèåñç ìíÞìç\n"
+
+#: src/passwd.c:845
+msgid "Cannot lock the TCFS key database; try again later\n"
+msgstr "Áäõíáìßá êëåéäþìáôïò ôçò âÜóçò êëåéäéþí ôïõ TCFS. ÄïêéìÜóôå áñãüôåñá\n"
+
+#: src/passwd.c:851
+msgid "Cannot open the TCFS key database.\n"
+msgstr "Áäõíáìßá áíïßãìáôïò ôçò âÜóçò êëåéäéþí ôïõ TCFS.\n"
+
+#: src/passwd.c:857
+msgid "Error updating the TCFS key database.\n"
+msgstr "ÓöÜëìá êáôÜ ôçí áíáíÝùóç ôçò âÜóçò êëåéäéþí ôïõ TCFS.\n"
+
+#: src/passwd.c:862
+msgid "Cannot commit TCFS changes.\n"
+msgstr "Áäõíáìßá õëïðïßçóçò ôùí áëëáãþí óôï TCFS.\n"
+
+#: src/passwd.c:1069
+#, c-format
+msgid "%s: Cannot execute %s"
+msgstr "%s: Áäõíáìßá åêôÝëåóçò ôïõ %s"
+
+#: src/passwd.c:1176
+#, c-format
+msgid "%s: repository %s not supported\n"
+msgstr "%s: ç áðïèÞêç %s äåí õðïóôçñßæåôáé\n"
+
+#: src/passwd.c:1263
+#, c-format
+msgid "%s: Permission denied\n"
+msgstr "%s: ¶äåéá áðïññßöèçêå\n"
+
+#: src/passwd.c:1287
+#, c-format
+msgid "You may not change the password for %s.\n"
+msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôï óõíèçìáôéêü ãéá ôï(í) %s.\n"
+
+#: src/passwd.c:1352
+#, c-format
+msgid "Changing password for %s\n"
+msgstr "ÁëëáãÞ óõíèçìáôéêïý ãéá ôïí %s\n"
+
+#: src/passwd.c:1356
+#, c-format
+msgid "The password for %s is unchanged.\n"
+msgstr "Ôï óõíèçìáôéêü ãéá ôïí %s äåí Üëëáîå.\n"
+
+#: src/passwd.c:1412
+msgid "Password changed.\n"
+msgstr "Ôï óõíèçìáôéêü Üëëáîå.\n"
+
+#: src/pwck.c:98
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"
+msgstr "×ñÞóç: %s [ -qr ] [ passwd [ shadow ] ]\n"
+
+#: src/pwck.c:100
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd ]\n"
+msgstr "×ñÞóç: %s [ -qr ] [ passwd ]\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:285
+msgid "invalid password file entry\n"
+msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï óõíèçìáôéêþí\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:347
+msgid "duplicate password entry\n"
+msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/pwck.c:363
+#, c-format
+msgid "invalid user name `%s'\n"
+msgstr "Ìç Ýãêõñï üíïìá ÷ñÞóôç `%s'\n"
+
+#: src/pwck.c:373
+#, c-format
+msgid "user %s: bad UID (%d)\n"
+msgstr "÷ñÞóôçò %s: ëáíèáóìÝíï UID (%d)\n"
+
+#.
+#. * No primary group, just give a warning
+#.
+#: src/pwck.c:388
+#, c-format
+msgid "user %s: no group %d\n"
+msgstr "÷ñÞóôçò %s: êáìéÜ ïìÜäá %d\n"
+
+#.
+#. * Home directory doesn't exist, give a warning
+#.
+#: src/pwck.c:403
+#, c-format
+msgid "user %s: directory %s does not exist\n"
+msgstr "÷ñÞóôçò %s: ï êáôÜëïãïò %s äåí õðÜñ÷åé\n"
+
+#.
+#. * Login shell doesn't exist, give a warning
+#.
+#: src/pwck.c:418
+#, c-format
+msgid "user %s: program %s does not exist\n"
+msgstr "÷ñÞóôçò %s: ôï ðñüãñáììá %s äåí õðÜñ÷åé\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:454
+msgid "invalid shadow password file entry\n"
+msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:516
+msgid "duplicate shadow password entry\n"
+msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#.
+#. * Tell the user this entry has no matching
+#. * /etc/passwd entry and ask them to delete it.
+#.
+#: src/pwck.c:540
+msgid "no matching password file entry\n"
+msgstr "Äåí âñÝèçêå êáôá÷þñçóç óôï áñ÷åßï óõíèçìáôéêþí ðïõ íá ôáéñßáæåé\n"
+
+#: src/pwck.c:557
+#, c-format
+msgid "user %s: last password change in the future\n"
+msgstr "÷ñÞóôçò %s: ôåëåõôáßá áëëáãÞ óõíèçìáôéêïý óôï ìÝëëïí\n"
+
+#: src/pwconv.c:94 src/pwunconv.c:108
+#, c-format
+msgid "%s: can't lock passwd file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/pwconv.c:99 src/pwunconv.c:113
+#, c-format
+msgid "%s: can't open passwd file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/pwconv.c:126
+#, c-format
+msgid "%s: can't remove shadow entry for %s\n"
+msgstr ""
+"áäõíáìßá áöáßñåóçò êáôá÷þñçóçò ãéá ôïí %s, áðü ôï áñ÷åßï óêéùäþí "
+"óõíèçìáôéêþí\n"
+
+#: src/pwconv.c:169
+#, c-format
+msgid "%s: can't update passwd entry for %s\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óõíèçìáôéêïý ãéá ôïí %s\n"
+
+#: src/pwconv.c:176
+#, c-format
+msgid "%s: can't update shadow file\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/pwconv.c:180
+#, c-format
+msgid "%s: can't update passwd file\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/pwunconv.c:62
+#, c-format
+msgid "%s: Shadow passwords are not configured.\n"
+msgstr "%s: Ôá óêéþäç óõíèçìáôéêÜ äåí Ý÷ïõí äéáìïñöùèåß.\n"
+
+#: src/pwunconv.c:171
+#, c-format
+msgid "%s: can't update entry for user %s\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò ãéá ôïí ÷ñÞóôç %s\n"
+
+#: src/pwunconv.c:188
+#, c-format
+msgid "%s: can't delete shadow password file\n"
+msgstr "%s: Äåí åßíáé äõíáôüí íá äéáãñáöåß ôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/su.c:140
+msgid "Sorry."
+msgstr "ËõðÜìáé."
+
+#: src/su.c:222
+#, c-format
+msgid "%s: must be run from a terminal\n"
+msgstr "%s: ðñÝðåé íá åêôåëåóôåß áðü ôåñìáôéêü\n"
+
+#: src/su.c:311
+#, c-format
+msgid "%s: pam_start: error %d\n"
+msgstr "%s: pam_start: óöÜëìá %d\n"
+
+#: src/su.c:337
+#, c-format
+msgid "Unknown id: %s\n"
+msgstr "Áãíùóôç ôáõôüôçôá: %s\n"
+
+#. access denied (-1) or unexpected value
+#: src/su.c:372 src/su.c:387
+#, c-format
+msgid "You are not authorized to su %s\n"
+msgstr "Äåí Ý÷åôå Üäåéá ãéá su %s\n"
+
+#. require own password
+#: src/su.c:383
+msgid "(Enter your own password.)"
+msgstr "(ÅéóÜãåôå ôï äéêü óáò óõíèçìáôéêü.)"
+
+#: src/su.c:404
+#, c-format
+msgid "%s: permission denied (shell).\n"
+msgstr "%s: Üäåéá áðïññßöèçêå (öëïéüò)\n"
+
+#: src/su.c:428
+#, c-format
+msgid ""
+"%s: %s\n"
+"(Ignored)\n"
+msgstr ""
+"%s: %s\n"
+"(ÁãíïÞèçêå)\n"
+
+#: src/su.c:628
+msgid "No shell\n"
+msgstr "Äåí õðÜñ÷åé öëïéüò\n"
+
+#. must be a password file!
+#: src/sulogin.c:136
+msgid "No password file\n"
+msgstr "Äåí õðÜñ÷åé áñ÷åßï óõíèçìáôéêþí\n"
+
+#.
+#. * Fail secure
+#.
+#: src/sulogin.c:178
+msgid "No password entry for 'root'\n"
+msgstr "Äåí õðÜñ÷åé êáôá÷þñçóç óõíèçìáôéêïý ãéá ôïí 'root'\n"
+
+#.
+#. * Here we prompt for the root password, or if no password is
+#. * given we just exit.
+#.
+#. get a password for root
+#: src/sulogin.c:192
+msgid ""
+"\n"
+"Type control-d to proceed with normal startup,\n"
+"(or give root password for system maintenance):"
+msgstr ""
+"\n"
+"ÐëçêôñïëïãÞóôå control-d ãéá íá óõíå÷ßóåôå ìå ôçí êáíïíéêÞ Ýíáñîç,\n"
+"(Þ äþóôå ôï óõíèçìáôéêü ôïõ root ãéá óõíôÞñçóç ôïõ óõóôÞìáôïò):"
+
+#. make new environment active
+#: src/sulogin.c:241
+msgid "Entering System Maintenance Mode\n"
+msgstr "¸íáñîç ÊáôÜóôáóçò ÓõíôÞñçóçò ÓõóôÞìáôïò\n"
+
+#: src/useradd.c:243
+#, c-format
+msgid "%s: rebuild the group database\n"
+msgstr "%s: åðáíáêôßóôå ôçí âÜóç äåäïìÝíùí ïìÜäùí\n"
+
+#: src/useradd.c:250
+#, c-format
+msgid "%s: rebuild the shadow group database\n"
+msgstr "%s: åðáíáêôßóôå ôçí âÜóç äåäïìÝíùí ôùí óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/useradd.c:287 src/usermod.c:967
+#, c-format
+msgid "%s: invalid numeric argument `%s'\n"
+msgstr "%s: Ìç Ýãêõñç áñéèìçôéêÞ ðáñÜìåôñïò `%s'\n"
+
+#: src/useradd.c:343
+#, c-format
+msgid "%s: unknown gid %s\n"
+msgstr "%s: Üãíùóôï gid %s\n"
+
+#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254
+#: src/usermod.c:1098
+#, c-format
+msgid "%s: unknown group %s\n"
+msgstr "%s: Üãíùóôç ïìÜäá %s\n"
+
+#: src/useradd.c:418
+#, c-format
+msgid "group=%s,%ld basedir=%s skel=%s\n"
+msgstr "ïìÜäá=%s,%ld âáóéêüò_êáôáë=%s óêåë=%s\n"
+
+#: src/useradd.c:421
+#, c-format
+msgid "shell=%s "
+msgstr "öëïéüò=%s "
+
+#: src/useradd.c:423
+#, c-format
+msgid "inactive=%ld expire=%s"
+msgstr "áíåíåñãü=%ld ëÞîç=%s"
+
+#: src/useradd.c:427
+#, c-format
+msgid "GROUP=%ld\n"
+msgstr "ÏÌÁÄÁ=%ld\n"
+
+#: src/useradd.c:428
+#, c-format
+msgid "HOME=%s\n"
+msgstr "ÌÇÔÑÉÊÏÓ_ÊÁÔÁËÏÃÏÓ=%s\n"
+
+#: src/useradd.c:430
+#, c-format
+msgid "INACTIVE=%ld\n"
+msgstr "ÁÍÅÍÅÑÃÏÓ=%ld\n"
+
+#: src/useradd.c:431
+#, c-format
+msgid "EXPIRE=%s\n"
+msgstr "ËÇÎÇ=%s\n"
+
+#: src/useradd.c:433
+#, c-format
+msgid "SHELL=%s\n"
+msgstr "ÊÅËÕÖÏÓ=%s\n"
+
+#: src/useradd.c:434
+#, c-format
+msgid "SKEL=%s\n"
+msgstr "ÓÊÅË=%s\n"
+
+#: src/useradd.c:470
+#, c-format
+msgid "%s: cannot create new defaults file\n"
+msgstr "%s: áäõíáìßá äçìéïõñãßáò íÝïõ áñ÷åßïõ ðñïêáèïñéóìÝíùí ñõèìßóåùí\n"
+
+#: src/useradd.c:564 src/useradd.c:575
+#, c-format
+msgid "%s: rename: %s"
+msgstr "%s: ìåôïíïìáóßá: %s"
+
+#: src/useradd.c:662 src/usermod.c:274
+#, c-format
+msgid "%s: group `%s' is a NIS group.\n"
+msgstr "%s: Ç ïìÜäá `%s' åßíáé NIS ïìÜäá.\n"
+
+#: src/useradd.c:670 src/usermod.c:282
+#, c-format
+msgid "%s: too many groups specified (max %d).\n"
+msgstr "%s: Ðñïóäéïñßóôçêáí õðåñâïëéêÝò ïìÜäåò (ìåã. %d).\n"
+
+#: src/useradd.c:702 src/usermod.c:314
+#, c-format
+msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"
+msgstr "÷ñÞóç: %s\t[-u uid [-o]] [-g ïìÜäá] [-G ïìÜäá,...] \n"
+
+#: src/useradd.c:705
+msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n"
+msgstr ""
+"\t\t[-d ìçôñéêüò_êáôÜëïãïò] [-s öëïéüò] [-c ó÷üëéï]\n"
+"\t\t[-m [-k êáíüíáò]]\n"
+
+#: src/useradd.c:708 src/usermod.c:320
+msgid "[-f inactive] [-e expire ] "
+msgstr "[-f áíåíåñãü] [-e ëÞîç ] "
+
+#: src/useradd.c:711
+msgid "[-A program] "
+msgstr "[-A ðñüãñáììá] "
+
+#: src/useradd.c:713
+msgid "[-p passwd] name\n"
+msgstr "[-p óõíèçìáôéêü] üíïìá\n"
+
+#: src/useradd.c:715
+#, c-format
+msgid " %s\t-D [-g group] [-b base] [-s shell]\n"
+msgstr " %s\t-D [-g ïìÜäá] [-b âÜóç] [-s öëïéüò]\n"
+
+#: src/useradd.c:718
+msgid "\t\t[-f inactive] [-e expire ]\n"
+msgstr "\t\t[-f áíåíåñãü] [-e ëÞîç ]\n"
+
+#: src/useradd.c:815 src/usermod.c:472
+#, c-format
+msgid "%s: error locking group file\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôï êëåßäùìá ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/useradd.c:819 src/usermod.c:477
+#, c-format
+msgid "%s: error opening group file\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôï Üíïéãìá ôïõ áñ÷åßïõ ïìÜäùí\n"
+
+#: src/useradd.c:824 src/usermod.c:584
+#, c-format
+msgid "%s: error locking shadow group file\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôï êëåßäùìá ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/useradd.c:829 src/usermod.c:590
+#, c-format
+msgid "%s: error opening shadow group file\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôï Üíïéãìá ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/useradd.c:1001
+#, c-format
+msgid "%s: uid %d is not unique\n"
+msgstr "%s: Ôï uid %d äåí åßíáé ìïíáäéêü\n"
+
+#: src/useradd.c:1031
+#, c-format
+msgid "%s: can't get unique uid\n"
+msgstr "%s: áäõíáìßá åõñåóçò ìïíáäéêïý uid\n"
+
+#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057
+#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157
+#, c-format
+msgid "%s: invalid field `%s'\n"
+msgstr "%s: Ìç Ýãêõñï ðåäßï `%s'\n"
+
+#: src/useradd.c:1153
+#, c-format
+msgid "%s: invalid base directory `%s'\n"
+msgstr "%s: Ìç Ýãêõñïò êáôÜëïãïò âÜóçò `%s'\n"
+
+#: src/useradd.c:1163
+#, c-format
+msgid "%s: invalid comment `%s'\n"
+msgstr "%s: Ìç Ýãêõñï ó÷üëéï `%s'\n"
+
+#: src/useradd.c:1173
+#, c-format
+msgid "%s: invalid home directory `%s'\n"
+msgstr "%s: Ìç Ýãêõñïò ìçôñéêüò êáôÜëïãïò ÷ñÞóôç `%s'\n"
+
+#: src/useradd.c:1191 src/usermod.c:1080
+#, c-format
+msgid "%s: invalid date `%s'\n"
+msgstr "%s: Ìç Ýãêõñç çìåñïìçíßá `%s'\n"
+
+#: src/useradd.c:1203
+#, c-format
+msgid "%s: shadow passwords required for -e\n"
+msgstr "%s: óêéþäç óõíèçìáôéêÜ áðáéôïýíôáé ãéá ôï -e\n"
+
+#: src/useradd.c:1218
+#, c-format
+msgid "%s: shadow passwords required for -f\n"
+msgstr "%s: óêéþäç óõíèçìáôéêÜ áðáéôïýíôáé ãéá -f\n"
+
+#: src/useradd.c:1292
+#, c-format
+msgid "%s: invalid shell `%s'\n"
+msgstr "%s: Ìç Ýãêõñïò öëïéüò `%s'\n"
+
+#: src/useradd.c:1333
+#, c-format
+msgid "%s: invalid user name `%s'\n"
+msgstr "%s: Ìç Ýãêõñï üíïìá ÷ñÞóôç `%s'\n"
+
+#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225
+#, c-format
+msgid "%s: cannot rewrite password file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230
+#, c-format
+msgid "%s: cannot rewrite shadow password file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265
+#, c-format
+msgid "%s: unable to lock password file\n"
+msgstr "%s: Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269
+#, c-format
+msgid "%s: unable to open password file\n"
+msgstr "%s: Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274
+#, c-format
+msgid "%s: cannot lock shadow password file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279
+#, c-format
+msgid "%s: cannot open shadow password file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1529 src/usermod.c:1366
+#, c-format
+msgid "%s: error adding authentication method\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç ìåèüäïõ åîáêñßâùóçò\n"
+
+#: src/useradd.c:1552
+#, c-format
+msgid "%s: error adding new password entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1567
+#, c-format
+msgid "%s: error updating password dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï dbm áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1583 src/usermod.c:1425
+#, c-format
+msgid "%s: error adding new shadow password entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí "
+"óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1599 src/usermod.c:1440
+#, c-format
+msgid "%s: error updating shadow passwd dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï dbm áñ÷åßï óêéùäþí "
+"óõíèçìáôéêþí\n"
+
+#: src/useradd.c:1631
+#, c-format
+msgid "%s: cannot create directory %s\n"
+msgstr "%s: áäõíáìßá äçìéïõñãßáò êáôáëüãïõ %s\n"
+
+#: src/useradd.c:1708 src/usermod.c:1203
+#, c-format
+msgid "%s: user %s exists\n"
+msgstr "%s: Ï ÷ñÞóôçò %s õðÜñ÷åé\n"
+
+#: src/useradd.c:1738
+#, c-format
+msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n"
+msgstr ""
+
+#: src/userdel.c:127
+#, c-format
+msgid "usage: %s [-r] name\n"
+msgstr "÷ñÞóç: %s [-r] üíïìá\n"
+
+#: src/userdel.c:178 src/userdel.c:260
+#, c-format
+msgid "%s: error updating group entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóçò ïìÜäáò\n"
+
+#: src/userdel.c:188 src/userdel.c:269
+#, c-format
+msgid "%s: cannot update dbm group entry\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ôçò dbm êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n"
+
+#: src/userdel.c:215
+#, fuzzy, c-format
+msgid "%s: cannot remove dbm group entry\n"
+msgstr "%s: áäõíáìßá áíáíÝùóçò ôçò dbm êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n"
+
+#: src/userdel.c:300
+#, c-format
+msgid "%s: cannot rewrite TCFS key file\n"
+msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ êëåéäéþí ôïõ TCFS\n"
+
+#: src/userdel.c:380
+#, c-format
+msgid "%s: cannot lock TCFS key file\n"
+msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ êëåéäéþí ôïõ TCFS\n"
+
+#: src/userdel.c:384
+#, c-format
+msgid "%s: cannot open TCFS key file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ êëåéäéþí ôïõ TCFS\n"
+
+#: src/userdel.c:393
+#, c-format
+msgid "%s: cannot open group file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ ïìÜäùí\n"
+
+#: src/userdel.c:403
+#, c-format
+msgid "%s: cannot open shadow group file\n"
+msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n"
+
+#: src/userdel.c:434 src/userdel.c:449
+#, c-format
+msgid "%s: error deleting authentication\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ åîáêñßâùóçò\n"
+
+#: src/userdel.c:458
+#, c-format
+msgid "%s: error deleting password entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/userdel.c:461
+#, c-format
+msgid "%s: error deleting shadow password entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/userdel.c:470
+#, c-format
+msgid "%s: error deleting TCFS entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò ôïõ TCFS\n"
+
+#: src/userdel.c:483
+#, c-format
+msgid "%s: error deleting password dbm entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï dbm áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/userdel.c:502
+#, c-format
+msgid "%s: error deleting shadow passwd dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï dbm áñ÷åßï óêéùäþí "
+"óõíèçìáôéêþí\n"
+
+#: src/userdel.c:543
+#, c-format
+msgid "%s: user %s is currently logged in\n"
+msgstr "%s: Ï ÷ñÞóôçò %s âñßóêåôáé óôï óýóôçìá\n"
+
+#: src/userdel.c:660
+#, c-format
+msgid "%s: warning: %s not owned by %s, not removing\n"
+msgstr "%s: ðñïåéäïðïßçóç: Ôï %s äåí áíÞêåé óôïí %s, äåí äéáãñÜöåôáé\n"
+
+#: src/userdel.c:666
+#, c-format
+msgid "%s: warning: can't remove "
+msgstr "%s: ðñïåéäïðïßçóç: áäõíáìßá äéáãñáöÞò "
+
+#: src/userdel.c:741 src/usermod.c:994
+#, c-format
+msgid "%s: user %s does not exist\n"
+msgstr "%s: Ï ÷ñÞóôçò %s äåí õðÜñ÷åé\n"
+
+#: src/userdel.c:755 src/usermod.c:1010
+#, c-format
+msgid "%s: user %s is a NIS user\n"
+msgstr "%s: Ï ÷ñÞóôçò %s åßíáé NIS ÷ñÞóôçò\n"
+
+#: src/userdel.c:792
+#, c-format
+msgid "%s: %s not owned by %s, not removing\n"
+msgstr "%s: Ôï %s äåí áíÞêåé óôïí %s, äåí áöáéñåßôáé\n"
+
+#: src/userdel.c:815
+#, c-format
+msgid "%s: not removing directory %s (would remove home of user %s)\n"
+msgstr ""
+"%s: Äåí äéáãñÜöåôáé ï êáôÜëïãïò %s (èá áöáéñïýóå ôïí ìçôñéêü êáôÜëïãï ôïõ "
+"÷ñÞóôç %s)\n"
+
+#: src/userdel.c:828
+#, c-format
+msgid "%s: error removing directory %s\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ ôïõ êáôáëüãïõ %s\n"
+
+#: src/usermod.c:317
+msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"
+msgstr ""
+"\t\t[-d ìçôñéêüò_êáôÜëïãïò [-m]] [-s öëïéüò] [-c ó÷üëéï]\n"
+"\t\t[-l íÝï_üíïìá]\n"
+
+#: src/usermod.c:323
+msgid "[-A {DEFAULT|program},... ] "
+msgstr "[-A {DEFAULT|ðñüãñáììá},... ] "
+
+#: src/usermod.c:325
+#, fuzzy
+msgid "[-p passwd] [-L|-U] name\n"
+msgstr "[-p óõíèçìáôéêü] üíïìá\n"
+
+#: src/usermod.c:504
+#, c-format
+msgid "%s: out of memory in update_group\n"
+msgstr "%s: äåí õðÜñ÷åé åëåýèåñç ìíÞìç óôï update_group\n"
+
+#: src/usermod.c:627
+#, c-format
+msgid "%s: out of memory in update_gshadow\n"
+msgstr "%s: óôï update_gshadow\n"
+
+#: src/usermod.c:1180
+#, c-format
+msgid "%s: no flags given\n"
+msgstr "%s: Äåí äüèçêáí åíäåßîåéò\n"
+
+#: src/usermod.c:1187
+#, c-format
+msgid "%s: shadow passwords required for -e and -f\n"
+msgstr "%s: óêéþäç óõíèçìáôéêÜ áðáéôïýíôáé ãéá ôï -e êáé -f\n"
+
+#: src/usermod.c:1208
+#, c-format
+msgid "%s: uid %ld is not unique\n"
+msgstr "%s: Ôï uid %ld äåí åßíáé ìïíáäéêü\n"
+
+#: src/usermod.c:1356
+#, c-format
+msgid "%s: error deleting authentication method\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ ìåèüäïõ åîáêñßâùóçò\n"
+
+#: src/usermod.c:1376
+#, c-format
+msgid "%s: error changing authentication method\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí áëëáãÞ ìåèüäïõ åîáêñßâùóçò\n"
+
+#: src/usermod.c:1393
+#, c-format
+msgid "%s: error changing password entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí áëëáãÞ êáôá÷þñçóçò óõíèçìáôéêïý\n"
+
+#: src/usermod.c:1399
+#, c-format
+msgid "%s: error removing password entry\n"
+msgstr "%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/usermod.c:1407
+#, c-format
+msgid "%s: error adding password dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï dbm áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/usermod.c:1414
+#, c-format
+msgid "%s: error removing passwd dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò áðü ôï dbm áñ÷åßï óõíèçìáôéêþí\n"
+
+#: src/usermod.c:1431
+#, c-format
+msgid "%s: error removing shadow password entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n"
+
+#: src/usermod.c:1446
+#, c-format
+msgid "%s: error removing shadow passwd dbm entry\n"
+msgstr ""
+"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï dbm áñ÷åßï óêéùäþí "
+"óõíèçìáôéêþí\n"
+
+#: src/usermod.c:1477
+#, c-format
+msgid "%s: directory %s exists\n"
+msgstr "%s: ï êáôÜëïãïò %s õðÜñ÷åé\n"
+
+#: src/usermod.c:1484
+#, c-format
+msgid "%s: can't create %s\n"
+msgstr "%s: áäõíáìßá äçìéïõñãßáò ôïõ %s\n"
+
+#: src/usermod.c:1490
+#, c-format
+msgid "%s: can't chown %s\n"
+msgstr "%s: Áäõíáìßá áëëáãÞò éäéïêôÞôç(chown) ôïõ %s\n"
+
+#: src/usermod.c:1506
+#, c-format
+msgid "%s: cannot rename directory %s to %s\n"
+msgstr "%s: áäõíáìßá ìåôïíïìáóßáò ôïõ êáôáëüãïõ %s óå %s\n"
+
+#. better leave it alone
+#: src/usermod.c:1603
+#, c-format
+msgid "%s: warning: %s not owned by %s\n"
+msgstr "%s: ðñïåéäïðïßçóç: Ôï %s äåí áíÞêåé óôïí %s\n"
+
+#: src/usermod.c:1609
+msgid "failed to change mailbox owner"
+msgstr "áðïôõ÷ßá áëëáãÞò ôïõ éäéïêôÞôç ôïõ ãñáììáôïêéâùôßïõ"
+
+#: src/usermod.c:1616
+msgid "failed to rename mailbox"
+msgstr "áðïôõ÷ßá ìåôïíïìáóßáò ãñáììáôïêéâùôßïõ"
+
+#: src/vipw.c:102
+#, c-format
+msgid ""
+"\n"
+"%s: %s is unchanged\n"
+msgstr ""
+"\n"
+"%s: Ôï %s äåí Üëëáîå\n"
+
+#: src/vipw.c:127
+#, fuzzy
+msgid "Couldn't lock file"
+msgstr "%s: áäõíáìßá îåêëåéäþìáôïò áñ÷åßïõ\n"
+
+#: src/vipw.c:134
+msgid "Couldn't make backup"
+msgstr ""
+
+#: src/vipw.c:187
+#, c-format
+msgid "%s: can't restore %s: %s (your changes are in %s)\n"
+msgstr "%s: áäõíáìßá åðáíáöïñÜò %s: %s (ïé áëëáãÝò åßíáé óôï %s)\n"
+
+#: src/vipw.c:226
+msgid ""
+"Usage:\n"
+"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n"
+"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n"
+msgstr ""
+"×ñÞóç:\n"
+"`vipw' óýíôáóåé ôï /etc/passwd `vipw -s' óõíôÜóóåé ôï /etc/shadow\n"
+"`vigr' óýíôáóåé ôï /etc/group `vigr -s' óõíôÜóóåé ôï /etc/gshadow\n"
+
+#~ msgid "Incorrect password for %s.\n"
+#~ msgstr "ÅóöáëìÝíï óõíèçìáôéêü ãéá ôïí %s.\n"
+
+#~ msgid "group not found\n"
+#~ msgstr "ç ïìÜäá äåí âñÝèçêå\n"
diff --git a/current/po/fr.gmo b/current/po/fr.gmo
new file mode 100644
index 00000000..93f5fb53
--- /dev/null
+++ b/current/po/fr.gmo
Binary files differ
diff --git a/current/po/fr.po b/current/po/fr.po
new file mode 100644
index 00000000..0af05aee
--- /dev/null
+++ b/current/po/fr.po
@@ -0,0 +1,2417 @@
+# shadow fr.po
+# Copyright (C) 1999 Free Software Foundation, Inc.
+# Vincent Renardias <vincent@ldsol.com>, 1999
+# Patches, suggestions, etc welcome.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: shadow 19990709\n"
+"POT-Creation-Date: 2000-09-02 20:40+0200\n"
+"PO-Revision-Date: 1999-07-09 20:02+0200\n"
+"Last-Translator: Vincent Renardias <vincent@ldsol.com>\n"
+"Language-Team: Vincent Renardias <vincent@ldsol.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmisc/addgrps.c:60
+#, c-format
+msgid "Warning: unknown group %s\n"
+msgstr "Avertissement: le groupe %s est inconnu\n"
+
+#: libmisc/addgrps.c:71
+msgid "Warning: too many groups\n"
+msgstr "Avertissement: trop de groupes\n"
+
+#: libmisc/age.c:104
+msgid "Your password has expired."
+msgstr "Votre mot de passe a expiré."
+
+#: libmisc/age.c:107
+msgid "Your password is inactive."
+msgstr "Votre mot de passe est désactivé."
+
+#: libmisc/age.c:110
+msgid "Your login has expired."
+msgstr "Votre compte a expiré."
+
+#: libmisc/age.c:127
+msgid " Contact the system administrator.\n"
+msgstr " Contactez l'administrateur système.\n"
+
+#: libmisc/age.c:130
+msgid " Choose a new password.\n"
+msgstr " Choisissez un nouveau mot de passe.\n"
+
+#: libmisc/age.c:228
+#, c-format
+msgid "Your password will expire in %ld days.\n"
+msgstr "Votre mot de passe expirera dans %ld jours.\n"
+
+#: libmisc/age.c:230
+msgid "Your password will expire tomorrow.\n"
+msgstr "Votre mot de passe expirera demain.\n"
+
+#: libmisc/age.c:232
+msgid "Your password will expire today.\n"
+msgstr "Votre mot de passe expirera aujourd'hui.\n"
+
+#: libmisc/chowntty.c:110
+#, c-format
+msgid "Unable to change tty %s"
+msgstr "Impossible de changer le tty %s"
+
+#: libmisc/env.c:160
+msgid "Environment overflow\n"
+msgstr "Dépassement de l'environnement\n"
+
+#: libmisc/env.c:200
+#, c-format
+msgid "You may not change $%s\n"
+msgstr "Vous ne pouvez pas changer $%s\n"
+
+#: libmisc/failure.c:238
+#, c-format
+msgid "%d %s since last login. Last was %s on %s.\n"
+msgstr "%d %s depuis la dernière connexion. La dernière fut le %s sur %s.\n"
+
+#: libmisc/failure.c:239
+msgid "failures"
+msgstr "échecs"
+
+#: libmisc/failure.c:239
+msgid "failure"
+msgstr "échec"
+
+#: libmisc/limits.c:397
+msgid "Too many logins.\n"
+msgstr "Trop de connexions.\n"
+
+#: libmisc/login_desrpc.c:63
+#, c-format
+msgid "Password does not decrypt secret key for %s.\n"
+msgstr "Le mot de passe ne décrypte pas le clé secréte pour %s.\n"
+
+#: libmisc/login_desrpc.c:69
+#, c-format
+msgid "Could not set %s's secret key: is the keyserv daemon running?\n"
+msgstr ""
+"Impossible de changer la clé secréte de %s : le daemon keyserv "
+"fonctionne-t-il?\n"
+
+#: libmisc/mail.c:62 libmisc/mail.c:77
+msgid "You have new mail."
+msgstr "Vous avez des nouveaux messages."
+
+#: libmisc/mail.c:73
+msgid "No mail."
+msgstr "Pas de courier."
+
+#: libmisc/mail.c:75
+msgid "You have mail."
+msgstr "Vous avez du courier."
+
+#: libmisc/obscure.c:281 src/passwd.c:309
+#, c-format
+msgid "Bad password: %s. "
+msgstr "Mauvais mot de passe: %s. "
+
+#: libmisc/pam_pass.c:42
+#, c-format
+msgid "passwd: pam_start() failed, error %d\n"
+msgstr "passwd: échec de pam_start(), erreur %d\n"
+
+#: libmisc/pam_pass.c:49
+#, c-format
+msgid "passwd: %s\n"
+msgstr "passwd: %s\n"
+
+#: libmisc/setupenv.c:205
+#, c-format
+msgid "Unable to cd to \"%s\"\n"
+msgstr "Impossible d'aller dans \"%s\"\n"
+
+#: libmisc/setupenv.c:213
+msgid "No directory, logging in with HOME=/"
+msgstr "Pas de répertoire, connexion avec HOME=/"
+
+#: libmisc/shell.c:78
+#, c-format
+msgid "Executing shell %s\n"
+msgstr "Exécution du shell %s\n"
+
+#.
+#. * Obviously something is really wrong - I can't figure out
+#. * how to execute this stupid shell, so I might as well give
+#. * up in disgust ...
+#.
+#: libmisc/shell.c:122
+#, c-format
+msgid "Cannot execute %s"
+msgstr "Impossible d'exécuter %s"
+
+#: libmisc/suauth.c:99
+msgid "Access to su to that account DENIED.\n"
+msgstr "Accès à su à partir de ce compte REFUSÉ.\n"
+
+#: libmisc/suauth.c:106
+msgid "Password authentication bypassed.\n"
+msgstr "Authentification par mot de passe court-circuitée.\n"
+
+#: libmisc/suauth.c:113
+msgid "Please enter your OWN password as authentication.\n"
+msgstr "Entrez VOTRE mot de passe comme identification.\n"
+
+#: libmisc/sub.c:61
+#, c-format
+msgid "Invalid root directory \"%s\"\n"
+msgstr "Répertoire root \"%s\" non valide\n"
+
+#: libmisc/sub.c:73
+#, c-format
+msgid "Can't change root directory to \"%s\"\n"
+msgstr "Impossible de changer le répertoire racine en \"%s\"\n"
+
+#: libmisc/xmalloc.c:28
+#, c-format
+msgid "malloc(%d) failed\n"
+msgstr "échec de malloc(%d)\n"
+
+#: lib/dialchk.c:71
+msgid "Dialup Password: "
+msgstr "Mot de passe dialup : "
+
+#: lib/getdef.c:253
+msgid "Could not allocate space for config info.\n"
+msgstr "Impossible d'allouer l'espace pour l'information sur la conf.\n"
+
+#.
+#. * Item was never found.
+#.
+#: lib/getdef.c:307
+#, c-format
+msgid "configuration error - unknown item '%s' (notify administrator)\n"
+msgstr ""
+"erreur de configuration - élément '%s' inconnu (avertissez "
+"l'administrateur)\n"
+
+#: lib/getdef.c:394
+#, c-format
+msgid "error - lookup '%s' failed\n"
+msgstr "erreur - échec de la recherche de '%s'\n"
+
+#: lib/getdef.c:402
+#, c-format
+msgid "%s not found\n"
+msgstr "%s non trouvé\n"
+
+#.
+#. * get the password from her, and set the salt for
+#. * the decryption from the group file.
+#.
+#: lib/pwauth.c:54 src/newgrp.c:305
+msgid "Password: "
+msgstr "Mot de passe: "
+
+#: lib/pwauth.c:56
+#, c-format
+msgid "%s's Password: "
+msgstr "Mot de passe de %s: "
+
+#: lib/pwauth.c:270
+msgid "(Echo on) "
+msgstr ""
+
+#: lib/strerror.c:20
+#, c-format
+msgid "Unknown error %d"
+msgstr "Erreur %d inconnue"
+
+#: src/chage.c:156
+#, c-format
+msgid ""
+"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n"
+" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"
+msgstr ""
+"Usage: %s [ -l ] [ -m min_jourss ] [ -M max_jours ]\n"
+" [ -W avertissement ] [ -I inactif ] [ -E expire ] [ -d dernier_jour ]\n"
+" utilisateur\n"
+
+#: src/chage.c:158
+#, c-format
+msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"
+msgstr ""
+"Usage: %s [ -l ] [ -m min_jours ] [ -M max_jours ] [ -d dernier_jour ] "
+"utilisateur\n"
+
+#: src/chage.c:193
+msgid ""
+"Enter the new value, or press return for the default\n"
+"\n"
+msgstr ""
+"Entrez la nouvelle valeur ou tapes Entrée pour la valeur par défaut\n"
+"\n"
+
+#: src/chage.c:196
+msgid "Minimum Password Age"
+msgstr "Age minimum du mot de passe"
+
+#: src/chage.c:201
+msgid "Maximum Password Age"
+msgstr "Age maximum du mot de passe"
+
+#: src/chage.c:207
+msgid "Last Password Change (YYYY-MM-DD)"
+msgstr "Dernier changement de mot de passe (YYYY-MM-DD)"
+
+#: src/chage.c:216
+msgid "Password Expiration Warning"
+msgstr "Avertissement d'expiration de mot de passe"
+
+#: src/chage.c:221
+msgid "Password Inactive"
+msgstr "Mot de passe désactivé"
+
+#: src/chage.c:227
+msgid "Account Expiration Date (YYYY-MM-DD)"
+msgstr "Date d'expiration du compte (YYYY-MM-DD)"
+
+#.
+#. * Start with the easy numbers - the number of days before the
+#. * password can be changed, the number of days after which the
+#. * password must be chaged, the number of days before the
+#. * password expires that the user is told, and the number of
+#. * days after the password expires that the account becomes
+#. * unusable.
+#.
+#: src/chage.c:281
+#, c-format
+msgid "Minimum:\t%ld\n"
+msgstr "Minimum :\t%ld\n"
+
+#: src/chage.c:282
+#, c-format
+msgid "Maximum:\t%ld\n"
+msgstr "Maximum :\t%ld\n"
+
+#: src/chage.c:284
+#, c-format
+msgid "Warning:\t%ld\n"
+msgstr "Avertissement :\t%ld\n"
+
+#: src/chage.c:285
+#, c-format
+msgid "Inactive:\t%ld\n"
+msgstr "Désactivé :\t%ld\n"
+
+#.
+#. * The "last change" date is either "Never" or the date the
+#. * password was last modified. The date is the number of
+#. * days since 1/1/1970.
+#.
+#: src/chage.c:294
+msgid "Last Change:\t\t"
+msgstr "Dernier changement :\t\t"
+
+#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340
+msgid "Never\n"
+msgstr "Jamais\n"
+
+#.
+#. * The password expiration date is determined from the last
+#. * change date plus the number of days the password is valid
+#. * for.
+#.
+#: src/chage.c:308
+msgid "Password Expires:\t"
+msgstr "Expiration du mot de passe :\t"
+
+#.
+#. * The account becomes inactive if the password is expired
+#. * for more than "inactdays". The expiration date is calculated
+#. * and the number of inactive days is added. The resulting date
+#. * is when the active will be disabled.
+#.
+#: src/chage.c:324
+#, fuzzy
+msgid "Password Inactive:\t"
+msgstr "Mot de passe désactivé"
+
+#.
+#. * The account will expire on the given date regardless of the
+#. * password expiring or not.
+#.
+#: src/chage.c:338
+#, fuzzy
+msgid "Account Expires:\t"
+msgstr "Expiration du mot de passe :\t"
+
+#: src/chage.c:486
+#, c-format
+msgid "%s: do not include \"l\" with other flags\n"
+msgstr "%s : ne pas include \"l\" avec les autres drapeaux\n"
+
+#: src/chage.c:498 src/chage.c:610 src/login.c:529
+#, c-format
+msgid "%s: permission denied\n"
+msgstr "%s : permission refusée\n"
+
+#: src/chage.c:510 src/chpasswd.c:120
+#, c-format
+msgid "%s: can't lock password file\n"
+msgstr "%s: impossible de vérouiller de fichier de mots de passe\n"
+
+#: src/chage.c:516 src/chpasswd.c:124
+#, c-format
+msgid "%s: can't open password file\n"
+msgstr "%s: impossible d'ouvrir le fichier de mots de passe\n"
+
+#: src/chage.c:523
+#, c-format
+msgid "%s: unknown user: %s\n"
+msgstr "%s: utilisateur inconnu: %s\n"
+
+#: src/chage.c:542
+#, c-format
+msgid "%s: can't lock shadow password file\n"
+msgstr "%s : impossible de vérouiller le fichier shadow password\n"
+
+#: src/chage.c:549
+#, c-format
+msgid "%s: can't open shadow password file\n"
+msgstr "%s : impossible d'ouvrir le fichier shadow password\n"
+
+#: src/chage.c:631
+#, c-format
+msgid "Changing the aging information for %s\n"
+msgstr "Changement des informations sur l'age pour %s\n"
+
+#: src/chage.c:633
+#, c-format
+msgid "%s: error changing fields\n"
+msgstr "%s : erreur lors du changement des champs\n"
+
+#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183
+#, c-format
+msgid "%s: can't update password file\n"
+msgstr "%s : impossible de mettre à jour le fichier passwd\n"
+
+#: src/chage.c:690 src/pwunconv.c:178
+#, c-format
+msgid "%s: can't update shadow password file\n"
+msgstr "%s : impossible de mettre à jour le fichier shadow password\n"
+
+#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409
+#: src/passwd.c:825 src/passwd.c:926
+msgid "Error updating the DBM password entry.\n"
+msgstr "Erreur durant la mise à jour de l'entrée du mot de passe DBM.\n"
+
+#: src/chage.c:771
+#, c-format
+msgid "%s: can't rewrite shadow password file\n"
+msgstr "%s : impossible de re-écrire le fichier shadow password\n"
+
+#: src/chage.c:785
+#, c-format
+msgid "%s: can't rewrite password file\n"
+msgstr "%s : impossible de re-écrire le fichier password\n"
+
+#: src/chage.c:836
+#, c-format
+msgid "%s: no aging information present\n"
+msgstr "%s : aucune information sur l'age\n"
+
+#: src/chfn.c:107
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n"
+"\t[ -h home_ph ] [ -o other ] [ user ]\n"
+msgstr ""
+"Usage: %s [ -f nom_complet ] [ -r no_bureau ] [ -w tel_bureau ]\n"
+"\t[ -h tel_perso ] [ -o autre ] [ utilisateur ]\n"
+
+#: src/chfn.c:111
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"
+msgstr "Usage: %s [ -f nom_complet ] [ -w no_bureau ] [ -h tel_bureau ]\n"
+
+#: src/chfn.c:163 src/chsh.c:119
+msgid "Enter the new value, or press return for the default\n"
+msgstr "Entrez la nouvelle valeur ou tapez Entrée pour le défaut\n"
+
+#: src/chfn.c:166
+msgid "Full Name"
+msgstr "Nom complet"
+
+#: src/chfn.c:168
+#, c-format
+msgid "\tFull Name: %s\n"
+msgstr "\tNom complet : %s\n"
+
+#: src/chfn.c:171
+msgid "Room Number"
+msgstr "No de bureau"
+
+#: src/chfn.c:173
+#, c-format
+msgid "\tRoom Number: %s\n"
+msgstr "\tNo de bureau : %s\n"
+
+#: src/chfn.c:176
+msgid "Work Phone"
+msgstr "Téléphone travail"
+
+#: src/chfn.c:178
+#, c-format
+msgid "\tWork Phone: %s\n"
+msgstr "\tTéléphone travail : %s\n"
+
+#: src/chfn.c:181
+msgid "Home Phone"
+msgstr "Téléphone perso"
+
+#: src/chfn.c:183
+#, c-format
+msgid "\tHome Phone: %s\n"
+msgstr "\tTéléphone perso : %s\n"
+
+#: src/chfn.c:186
+msgid "Other"
+msgstr "Autre"
+
+#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330
+#: src/chfn.c:391 src/passwd.c:1226
+#, c-format
+msgid "%s: Permission denied.\n"
+msgstr "%s: Permission refusée.\n"
+
+#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277
+#, c-format
+msgid "%s: Unknown user %s\n"
+msgstr "%s: Utilisateur %s inconnu\n"
+
+#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207
+#, c-format
+msgid "%s: Cannot determine your user name.\n"
+msgstr "%s: Impossible de déterminer votre nom d'utilisateur.\n"
+
+#: src/chfn.c:373 src/chsh.c:250
+#, c-format
+msgid "%s: cannot change user `%s' on NIS client.\n"
+msgstr "%s: impossible de changer l'utilisateur `%' sur le client NIS.\n"
+
+#: src/chfn.c:378 src/chsh.c:257
+#, c-format
+msgid "%s: `%s' is the NIS master for this client.\n"
+msgstr "%s: `%s' est le maître NIS pour ce client.\n"
+
+#: src/chfn.c:453
+#, c-format
+msgid "Changing the user information for %s\n"
+msgstr "Changement de l'information utilisateur pour %s\n"
+
+#: src/chfn.c:462
+#, c-format
+msgid "%s: invalid name: \"%s\"\n"
+msgstr "%s : nom non valide : \"%s\"\n"
+
+#: src/chfn.c:467
+#, c-format
+msgid "%s: invalid room number: \"%s\"\n"
+msgstr "%s : no de bureau non valide : \"%s\"\n"
+
+#: src/chfn.c:472
+#, c-format
+msgid "%s: invalid work phone: \"%s\"\n"
+msgstr "%s : téléphone du bureau non valide : \"%s\"\n"
+
+#: src/chfn.c:477
+#, c-format
+msgid "%s: invalid home phone: \"%s\"\n"
+msgstr "%s : téléphone perso non valide : \"%s\"\n"
+
+#: src/chfn.c:482
+#, c-format
+msgid "%s: \"%s\" contains illegal characters\n"
+msgstr "%s : \"%s\" contient des caractères non valide\n"
+
+#: src/chfn.c:494
+#, c-format
+msgid "%s: fields too long\n"
+msgstr "%s: champs trop longs\n"
+
+#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388
+msgid "Cannot change ID to root.\n"
+msgstr "Impossible de changer l'ID en root.\n"
+
+#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880
+msgid "Cannot lock the password file; try again later.\n"
+msgstr ""
+"Impossible de vérouiller le fichier de mots de passe; essayez plus tard.\n"
+
+#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885
+msgid "Cannot open the password file.\n"
+msgstr "Impossible d'ouvrir le fichier de mots de passe.\n"
+
+#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313
+#, c-format
+msgid "%s: %s not found in /etc/passwd\n"
+msgstr "%s: %s non trouvé dans /etc/passwd\n"
+
+#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920
+#: src/passwd.c:960
+msgid "Error updating the password entry.\n"
+msgstr "Erreur durant la mise à jour du mot de passe.\n"
+
+#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933
+msgid "Cannot commit password file changes.\n"
+msgstr "Impossible de valider le changement de mot de passe.\n"
+
+#: src/chfn.c:592 src/chsh.c:431
+msgid "Cannot unlock the password file.\n"
+msgstr "Impossible de dévérouiller le fichier de mots de passe.\n"
+
+#: src/chpasswd.c:76
+#, c-format
+msgid "usage: %s [-e]\n"
+msgstr "usage: %s [-e]\n"
+
+#: src/chpasswd.c:132 src/pwconv.c:104
+#, c-format
+msgid "%s: can't lock shadow file\n"
+msgstr "%s: impossible de vérouiller le fichier shadow\n"
+
+#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118
+#: src/pwunconv.c:123
+#, c-format
+msgid "%s: can't open shadow file\n"
+msgstr "%s: impossible d'ouvrir le fichier shadow\n"
+
+#: src/chpasswd.c:159 src/newusers.c:415
+#, c-format
+msgid "%s: line %d: line too long\n"
+msgstr "%s: ligne %d: ligne trop longue\n"
+
+#: src/chpasswd.c:179
+#, c-format
+msgid "%s: line %d: missing new password\n"
+msgstr "%s: ligne %d: nouveau mot de passe manquant\n"
+
+#: src/chpasswd.c:195
+#, c-format
+msgid "%s: line %d: unknown user %s\n"
+msgstr "%s: ligne %d: utilisateur %s inconnu\n"
+
+#: src/chpasswd.c:247
+#, c-format
+msgid "%s: line %d: cannot update password entry\n"
+msgstr "%s: ligne %d: impossible de mettre le mot de passe à jour\n"
+
+#: src/chpasswd.c:263 src/newusers.c:535
+#, c-format
+msgid "%s: error detected, changes ignored\n"
+msgstr "%s: erreur détectée; changements ignorés\n"
+
+#: src/chpasswd.c:274
+#, c-format
+msgid "%s: error updating shadow file\n"
+msgstr "%s: erreur lors de la mise à jour du fichier shadow\n"
+
+#: src/chpasswd.c:282
+#, c-format
+msgid "%s: error updating password file\n"
+msgstr "%s: erreur lors de la mise à jour du fichier de mots de passe\n"
+
+#: src/chsh.c:105
+#, c-format
+msgid "Usage: %s [ -s shell ] [ name ]\n"
+msgstr "Usage: %s [ -s shell ] [ nom ]\n"
+
+#: src/chsh.c:120
+msgid "Login Shell"
+msgstr "Shell de login"
+
+#: src/chsh.c:273 src/chsh.c:286
+#, c-format
+msgid "You may not change the shell for %s.\n"
+msgstr "Vous ne pouvez pas changer le shell de %s.\n"
+
+#: src/chsh.c:315
+#, c-format
+msgid "Changing the login shell for %s\n"
+msgstr "Changement du shell de login pour %s\n"
+
+#: src/chsh.c:327
+#, c-format
+msgid "%s: Invalid entry: %s\n"
+msgstr "%s: Entrée non valide : %s\n"
+
+#: src/chsh.c:332
+#, c-format
+msgid "%s is an invalid shell.\n"
+msgstr "%s n'est pas un shell valide.\n"
+
+#: src/dpasswd.c:69
+#, c-format
+msgid "Usage: %s [ -(a|d) ] shell\n"
+msgstr "Usage: %s [ -(a|d) ] shell\n"
+
+#: src/dpasswd.c:134
+msgid "Shell password: "
+msgstr "Mot de passe shell : "
+
+#: src/dpasswd.c:140
+msgid "re-enter Shell password: "
+msgstr "Confirmez le mot de passe shell : "
+
+#: src/dpasswd.c:147
+#, c-format
+msgid "%s: Passwords do not match, try again.\n"
+msgstr "%s : Les mots de passe ne correspondent pas, essayez encore.\n"
+
+#: src/dpasswd.c:167
+#, c-format
+msgid "%s: can't create %s"
+msgstr "%s: impossible de créer %s"
+
+#: src/dpasswd.c:172
+#, c-format
+msgid "%s: can't open %s"
+msgstr "%s : impossible d'ouvrir %s"
+
+#: src/dpasswd.c:200
+#, c-format
+msgid "%s: Shell %s not found.\n"
+msgstr "%s : Shell %s non trouvé.\n"
+
+#: src/expiry.c:84
+msgid "Usage: expiry { -f | -c }\n"
+msgstr "Usage : expiry { -f | -c }\n"
+
+#: src/expiry.c:137
+#, c-format
+msgid "%s: WARNING! Must be set-UID root!\n"
+msgstr "%s: AVERTISSEMENT! Devrait être set-UID root!\n"
+
+#: src/expiry.c:148
+#, c-format
+msgid "%s: unknown user\n"
+msgstr "%s : utilisateur inconnu\n"
+
+#: src/faillog.c:79
+#, c-format
+msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"
+msgstr "usage: %s [-a|-u utilisateur] [-m max] [-r] [-t jours] [-l sec_ver]\n"
+
+#: src/faillog.c:134 src/lastlog.c:94
+#, c-format
+msgid "Unknown User: %s\n"
+msgstr "Utilisateur %s inconnu\n"
+
+#: src/faillog.c:215
+msgid "Username Failures Maximum Latest\n"
+msgstr "Utilisateur Échecs Maximum Dernier\n"
+
+#: src/faillog.c:232
+#, c-format
+msgid " %s on %s"
+msgstr " %s sur %s"
+
+#: src/faillog.c:236
+#, c-format
+msgid " [%lds left]"
+msgstr " [%lds restant]"
+
+#: src/faillog.c:239
+#, c-format
+msgid " [%lds lock]"
+msgstr " [%lds verrou]"
+
+#: src/gpasswd.c:89
+#, c-format
+msgid "usage: %s [-r|-R] group\n"
+msgstr "usage: %s [-r|-R] groupe\n"
+
+#: src/gpasswd.c:90
+#, c-format
+msgid " %s [-a user] group\n"
+msgstr " %s [-a utilisateur] groupe\n"
+
+#: src/gpasswd.c:91
+#, c-format
+msgid " %s [-d user] group\n"
+msgstr " %s [-d utilisateur] groupe\n"
+
+#: src/gpasswd.c:93
+#, c-format
+msgid " %s [-A user,...] [-M user,...] group\n"
+msgstr " %s [-A utilisateur,...] [-M utilisateur,...] groupe\n"
+
+#: src/gpasswd.c:96
+#, c-format
+msgid " %s [-M user,...] group\n"
+msgstr " %s [-M utilisateur,...] groupe\n"
+
+#: src/gpasswd.c:160 src/gpasswd.c:245
+#, c-format
+msgid "%s: unknown user %s\n"
+msgstr "%s : utilisateur %s inconnu\n"
+
+#: src/gpasswd.c:172
+msgid "Permission denied.\n"
+msgstr "Permission refusée.\n"
+
+#: src/gpasswd.c:257
+#, c-format
+msgid "%s: shadow group passwords required for -A\n"
+msgstr "%s : mots de passe shadow nécessaires pour -A\n"
+
+#: src/gpasswd.c:308
+msgid "Who are you?\n"
+msgstr "Qui êtes vous?\n"
+
+#: src/gpasswd.c:328 src/newgrp.c:251
+#, c-format
+msgid "unknown group: %s\n"
+msgstr "groupe inconnu : %s\n"
+
+#: src/gpasswd.c:436
+#, c-format
+msgid "Adding user %s to group %s\n"
+msgstr "Ajout de l'utilisateur %s au groupe %s\n"
+
+#: src/gpasswd.c:453
+#, c-format
+msgid "Removing user %s from group %s\n"
+msgstr "Retrait de l'utilisateur %s du groupe %s\n"
+
+#: src/gpasswd.c:466
+#, c-format
+msgid "%s: unknown member %s\n"
+msgstr "%s : membre %s inconnu\n"
+
+#: src/gpasswd.c:513
+#, c-format
+msgid "%s: Not a tty\n"
+msgstr "%s : N'est pas un tty\n"
+
+#.
+#. * A new password is to be entered and it must be encrypted,
+#. * etc. The password will be prompted for twice, and both
+#. * entries must be identical. There is no need to validate
+#. * the old password since the invoker is either the group
+#. * owner, or root.
+#.
+#: src/gpasswd.c:535
+#, c-format
+msgid "Changing the password for group %s\n"
+msgstr "Changement du mot de passe pour le group %s\n"
+
+#: src/gpasswd.c:538
+msgid "New Password: "
+msgstr "Nouveau mot de passe : "
+
+#: src/gpasswd.c:543 src/passwd.c:422
+msgid "Re-enter new password: "
+msgstr "Nouveau mot de passe (à nouveau) : "
+
+#: src/gpasswd.c:555
+msgid "They don't match; try again"
+msgstr "Ils ne sont pas identiques; essayez à nouveau"
+
+#: src/gpasswd.c:559
+#, c-format
+msgid "%s: Try again later\n"
+msgstr "%s: Essayez à nouveau plus tard\n"
+
+#: src/gpasswd.c:590
+#, c-format
+msgid "%s: can't get lock\n"
+msgstr "%s : impossible d'obtenir le verrou\n"
+
+#: src/gpasswd.c:596
+#, c-format
+msgid "%s: can't get shadow lock\n"
+msgstr "%s : impossible d'obtenir le verrou sur shadow\n"
+
+#: src/gpasswd.c:602
+#, c-format
+msgid "%s: can't open file\n"
+msgstr "%s : impossible d'ouvrir le fichier\n"
+
+#: src/gpasswd.c:614
+#, c-format
+msgid "%s: can't update entry\n"
+msgstr "%s : impossible de mettre à jour l'entrée\n"
+
+#: src/gpasswd.c:620
+#, c-format
+msgid "%s: can't update shadow entry\n"
+msgstr "%s : impossible de mettre à jour l'entrée shadow\n"
+
+#: src/gpasswd.c:626
+#, c-format
+msgid "%s: can't re-write file\n"
+msgstr "%s : impossible de re-écrire le fichier\n"
+
+#: src/gpasswd.c:632
+#, c-format
+msgid "%s: can't re-write shadow file\n"
+msgstr "%s : impossible de re-écrire le fichier shadow\n"
+
+#: src/gpasswd.c:640
+#, c-format
+msgid "%s: can't unlock file\n"
+msgstr "%s : impossible de dévérouiller le fichier\n"
+
+#: src/gpasswd.c:645
+#, c-format
+msgid "%s: can't update DBM files\n"
+msgstr "%s : impossible de mettre à jours les fichiers DBM\n"
+
+#: src/gpasswd.c:652
+#, c-format
+msgid "%s: can't update DBM shadow files\n"
+msgstr "%s : impossible de mettre à jours les fichiers DBM shadow\n"
+
+#: src/groupadd.c:105
+msgid "usage: groupadd [-g gid [-o]] group\n"
+msgstr "usage: groupadd [-g gid [-o]] groupe\n"
+
+#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230
+#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675
+#, c-format
+msgid "%s: error adding new group entry\n"
+msgstr "%s : erreur durant l'addition du nouveau groupe\n"
+
+#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942
+#: src/usermod.c:551 src/usermod.c:687
+#, c-format
+msgid "%s: cannot add new dbm group entry\n"
+msgstr "%s : impossible d'ajouter une nouvelle entrée pour le groupe dbm\n"
+
+#: src/groupadd.c:258 src/useradd.c:996
+#, c-format
+msgid "%s: name %s is not unique\n"
+msgstr "%s : le nom %s n'est pas unique\n"
+
+#: src/groupadd.c:273
+#, c-format
+msgid "%s: gid %ld is not unique\n"
+msgstr "%s : le gid %ld n'est pas unique\n"
+
+#: src/groupadd.c:297
+#, c-format
+msgid "%s: can't get unique gid\n"
+msgstr "%s : impossible d'obtenir un gid unique\n"
+
+#.
+#. * All invalid group names land here.
+#.
+#: src/groupadd.c:321 src/groupmod.c:341
+#, c-format
+msgid "%s: %s is a not a valid group name\n"
+msgstr "%s : %s n'est pas un nom de groupe valide\n"
+
+#: src/groupadd.c:350 src/groupmod.c:367
+#, c-format
+msgid "%s: invalid group %s\n"
+msgstr "%s : groupe %s non valide\n"
+
+#: src/groupadd.c:367 src/useradd.c:1272
+#, c-format
+msgid "%s: -O requires NAME=VALUE\n"
+msgstr "%s : -O requiert NAME=VALEUR\n"
+
+#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381
+#: src/userdel.c:303 src/usermod.c:563
+#, c-format
+msgid "%s: cannot rewrite group file\n"
+msgstr "%s : impossible de re-écrire le fichier group\n"
+
+#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389
+#: src/userdel.c:309 src/usermod.c:700
+#, c-format
+msgid "%s: cannot rewrite shadow group file\n"
+msgstr "%s : impossible de re-écrire le fichier shadow group\n"
+
+#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389
+#, c-format
+msgid "%s: unable to lock group file\n"
+msgstr "%s : impossible de vérouiller le fichier group\n"
+
+#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432
+#, c-format
+msgid "%s: unable to open group file\n"
+msgstr "%s : impossible d'ouvrir le fichier group\n"
+
+#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398
+#, c-format
+msgid "%s: unable to lock shadow group file\n"
+msgstr "%s : impossible de vérouiller le fichier group\n"
+
+#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442
+#, c-format
+msgid "%s: unable to open shadow group file\n"
+msgstr "%s : impossible d'ouvrir le fichier shadow group\n"
+
+#: src/groupadd.c:518
+#, c-format
+msgid "%s: group %s exists\n"
+msgstr "%s : le groupe %s existe\n"
+
+#: src/groupdel.c:86
+msgid "usage: groupdel group\n"
+msgstr "usage: groupdel groupe\n"
+
+#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234
+#, c-format
+msgid "%s: error removing group entry\n"
+msgstr "%s : erreur lors de retrait de l'entrée du groupe\n"
+
+#: src/groupdel.c:116 src/groupmod.c:206
+#, c-format
+msgid "%s: error removing group dbm entry\n"
+msgstr "%s : erreur lors du retrait de l'entrée dbm du groupe\n"
+
+#: src/groupdel.c:131
+#, c-format
+msgid "%s: error removing shadow group entry\n"
+msgstr "%s : erreur lors du retrait de l'entrée shadow du groupe\n"
+
+#: src/groupdel.c:144 src/groupmod.c:252
+#, c-format
+msgid "%s: error removing shadow group dbm entry\n"
+msgstr "%s : erreur lors du retrait de l'entrée dbm shadow du groupe\n"
+
+#.
+#. * Can't remove the group.
+#.
+#: src/groupdel.c:248
+#, c-format
+msgid "%s: cannot remove user's primary group.\n"
+msgstr "%s : impossible d'enlever l'utilisateur de son groupe primaire.\n"
+
+#: src/groupdel.c:305 src/groupmod.c:501
+#, c-format
+msgid "%s: group %s does not exist\n"
+msgstr "%s : le groupe %s n'existe pas\n"
+
+#: src/groupdel.c:319 src/groupmod.c:517
+#, c-format
+msgid "%s: group %s is a NIS group\n"
+msgstr "%s : le groupe %s est un groupe NIS\n"
+
+#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016
+#, c-format
+msgid "%s: %s is the NIS master\n"
+msgstr "%s : %s est le maître NIS\n"
+
+#: src/groupmod.c:105
+msgid "usage: groupmod [-g gid [-o]] [-n name] group\n"
+msgstr "usage : groupmod [-g gid [-o]] [-n nom] groupe\n"
+
+#: src/groupmod.c:165
+#, c-format
+msgid "%s: %s not found in /etc/group\n"
+msgstr "%s : %s non trouvé dans /etc/group\n"
+
+#: src/groupmod.c:246
+#, c-format
+msgid "%s: cannot add new dbm shadow group entry\n"
+msgstr "%s : impossible d'ajouter une nouvelle entrée dbm shadow group\n"
+
+#: src/groupmod.c:299
+#, c-format
+msgid "%s: %ld is not a unique gid\n"
+msgstr "%s : %ld n'est pas un gid unique\n"
+
+#: src/groupmod.c:330
+#, c-format
+msgid "%s: %s is not a unique name\n"
+msgstr "%s : %s n'est pas un nom unique\n"
+
+#: src/groups.c:62
+#, c-format
+msgid "unknown user %s\n"
+msgstr "utilisateur %s inconnu\n"
+
+#: src/grpck.c:98
+#, c-format
+msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n"
+msgstr "Usage : %s [ -r ] ] groupe [ gshadow ] ]\n"
+
+#: src/grpck.c:100
+#, c-format
+msgid "Usage: %s [ -r ] [ group ]\n"
+msgstr "Usage: %s [ -r ] [ groupe ]\n"
+
+#: src/grpck.c:119 src/pwck.c:119
+msgid "No"
+msgstr "Non"
+
+#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225
+#, c-format
+msgid "%s: cannot lock file %s\n"
+msgstr "%s : impossible de vérouiller le fichier %s\n"
+
+#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241
+#: src/pwck.c:250
+#, c-format
+msgid "%s: cannot open file %s\n"
+msgstr "%s : impossible d'ouvrir le fichier %s\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:298
+msgid "invalid group file entry\n"
+msgstr "entrée dans le fichier group non valide\n"
+
+#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517
+#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517
+#: src/pwck.c:541
+#, c-format
+msgid "delete line `%s'? "
+msgstr "effacer la ligne `%s'? "
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:361
+msgid "duplicate group entry\n"
+msgstr "entrée de groupe dupliquée\n"
+
+#: src/grpck.c:378
+#, c-format
+msgid "invalid group name `%s'\n"
+msgstr "nom de groupe `%s' non valide\n"
+
+#: src/grpck.c:388
+#, c-format
+msgid "group %s: bad GID (%d)\n"
+msgstr "groupe %s : mauvais GID (%d)\n"
+
+#: src/grpck.c:414
+#, c-format
+msgid "group %s: no user %s\n"
+msgstr "groupe %s : pas d'utilisateur %s\n"
+
+#: src/grpck.c:416 src/grpck.c:585
+#, c-format
+msgid "delete member `%s'? "
+msgstr "effacer le membre `%s'? "
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:453
+msgid "invalid shadow group file entry\n"
+msgstr "entrée non valide dans le fichier shadow group\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:516
+msgid "duplicate shadow group entry\n"
+msgstr "entrée dupliquée dans le fichier shadow group\n"
+
+#: src/grpck.c:533
+msgid "no matching group file entry\n"
+msgstr "aucune entrée dans le fichier group correspondante\n"
+
+#: src/grpck.c:553
+#, c-format
+msgid "shadow group %s: no administrative user %s\n"
+msgstr "groupe shadow %s : aucun administrateur %s\n"
+
+#: src/grpck.c:555
+#, c-format
+msgid "delete administrative member `%s'? "
+msgstr "effacer le membre administrateur `%s' ?"
+
+#: src/grpck.c:583
+#, c-format
+msgid "shadow group %s: no user %s\n"
+msgstr "groupe shadow %s : aucun utilisateur %s\n"
+
+#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580
+#, c-format
+msgid "%s: cannot update file %s\n"
+msgstr "%s : impossible de mettre à jour le fichier %s\n"
+
+#: src/grpck.c:640 src/pwck.c:606
+#, c-format
+msgid "%s: the files have been updated; run mkpasswd\n"
+msgstr "%s : les fichiers ont été mis à jour; exécutez mkpasswd\n"
+
+#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611
+#, c-format
+msgid "%s: no changes\n"
+msgstr ""
+
+#: src/grpck.c:644 src/pwck.c:610
+#, c-format
+msgid "%s: the files have been updated\n"
+msgstr ""
+
+#: src/grpconv.c:62 src/grpunconv.c:63
+#, c-format
+msgid "%s: can't lock group file\n"
+msgstr ""
+
+#: src/grpconv.c:67 src/grpunconv.c:68
+#, c-format
+msgid "%s: can't open group file\n"
+msgstr ""
+
+#: src/grpconv.c:72 src/grpunconv.c:73
+#, c-format
+msgid "%s: can't lock shadow group file\n"
+msgstr ""
+
+#: src/grpconv.c:77 src/grpunconv.c:78
+#, c-format
+msgid "%s: can't open shadow group file\n"
+msgstr ""
+
+#.
+#. * This shouldn't happen (the entry exists) but...
+#.
+#: src/grpconv.c:93
+#, c-format
+msgid "%s: can't remove shadow group %s\n"
+msgstr ""
+
+#: src/grpconv.c:134 src/pwconv.c:160
+#, c-format
+msgid "%s: can't update shadow entry for %s\n"
+msgstr ""
+
+#: src/grpconv.c:143 src/grpunconv.c:94
+#, c-format
+msgid "%s: can't update entry for group %s\n"
+msgstr ""
+
+#: src/grpconv.c:150 src/grpunconv.c:102
+#, c-format
+msgid "%s: can't update shadow group file\n"
+msgstr ""
+
+#: src/grpconv.c:154 src/grpunconv.c:107
+#, c-format
+msgid "%s: can't update group file\n"
+msgstr ""
+
+#: src/grpconv.c:169 src/grpunconv.c:128
+#, c-format
+msgid "%s: not configured for shadow group support.\n"
+msgstr ""
+
+#: src/grpunconv.c:112
+#, c-format
+msgid "%s: can't delete shadow group file\n"
+msgstr ""
+
+#: src/id.c:56
+msgid "usage: id [ -a ]\n"
+msgstr "Usage : id [ -a ]\n"
+
+#: src/id.c:58
+msgid "usage: id\n"
+msgstr "Usage : id\n"
+
+#: src/id.c:118
+#, c-format
+msgid "uid=%d(%s)"
+msgstr "uid=%d(%s)"
+
+#: src/id.c:120
+#, c-format
+msgid "uid=%d"
+msgstr "uid=%d"
+
+#: src/id.c:124
+#, c-format
+msgid " gid=%d(%s)"
+msgstr " gid=%d(%s)"
+
+#: src/id.c:126
+#, c-format
+msgid " gid=%d"
+msgstr " gid=%d"
+
+#: src/id.c:136
+#, c-format
+msgid " euid=%d(%s)"
+msgstr " euid=%d(%s)"
+
+#: src/id.c:138
+#, c-format
+msgid " euid=%d"
+msgstr " euid=%d"
+
+#: src/id.c:143
+#, c-format
+msgid " egid=%d(%s)"
+msgstr " egid=%d(%s)"
+
+#: src/id.c:145
+#, c-format
+msgid " egid=%d"
+msgstr " egid=%d"
+
+#.
+#. * Start off the group message. It will be of the format
+#. *
+#. * groups=###(aaa),###(aaa),###(aaa)
+#. *
+#. * where "###" is a numerical value and "aaa" is the
+#. * corresponding name for each respective numerical value.
+#.
+#: src/id.c:166
+msgid " groups="
+msgstr " groupes="
+
+#: src/lastlog.c:167
+msgid "Username Port From Latest\n"
+msgstr "Utilisateur Port Venant de Dernière\n"
+
+#: src/lastlog.c:169
+msgid "Username Port Latest\n"
+msgstr "Utilisateur Port Dernière\n"
+
+#: src/lastlog.c:183
+msgid "**Never logged in**"
+msgstr "**Jamais connecté**"
+
+#: src/login.c:198
+#, c-format
+msgid "usage: %s [-p] [name]\n"
+msgstr "Usage : %s [-p] [nom]\n"
+
+#: src/login.c:201
+#, c-format
+msgid " %s [-p] [-h host] [-f name]\n"
+msgstr " %s [-p] [-h hôte] [-f nom]\n"
+
+#: src/login.c:203
+#, c-format
+msgid " %s [-p] -r host\n"
+msgstr " %s [-p] -r hôte\n"
+
+#: src/login.c:286
+msgid "Invalid login time\n"
+msgstr "Heure de connexion non valide\n"
+
+#: src/login.c:341
+msgid ""
+"\n"
+"System closed for routine maintenance\n"
+msgstr ""
+"\n"
+"Système fermé pour maintenance\n"
+
+#: src/login.c:351
+msgid ""
+"\n"
+"[Disconnect bypassed -- root login allowed.]\n"
+msgstr ""
+"\n"
+"[Disconnexion court-circuitée -- login root authorisé.]\n"
+
+#: src/login.c:390
+#, c-format
+msgid ""
+"\n"
+"Login timed out after %d seconds.\n"
+msgstr ""
+"\n"
+"Tentative de connexion: délai de %s secondes dépassé.\n"
+
+#: src/login.c:692
+#, c-format
+msgid " on `%.100s' from `%.200s'"
+msgstr " sur `%.100s' à partir de `%.200s'"
+
+#: src/login.c:694
+#, c-format
+msgid " on `%.100s'"
+msgstr " sur `%.100s'"
+
+#: src/login.c:834
+#, c-format
+msgid ""
+"\n"
+"%s login: "
+msgstr ""
+"\n"
+"% login: "
+
+#: src/login.c:836
+msgid "login: "
+msgstr "login: "
+
+#: src/login.c:1026 src/sulogin.c:231
+msgid "Login incorrect"
+msgstr "Login incorrect"
+
+#: src/login.c:1213
+msgid "Warning: login re-enabled after temporary lockout.\n"
+msgstr "Avertissement: login réactivé après une désactivation temporaire.\n"
+
+#: src/login.c:1223
+#, c-format
+msgid "Last login: %s on %s"
+msgstr "Dernière connexion : le %s sur %s"
+
+#: src/login.c:1226
+#, c-format
+msgid "Last login: %.19s on %s"
+msgstr "Dernière connexion : le %.19s sur %s"
+
+#: src/login.c:1231
+#, c-format
+msgid " from %.*s"
+msgstr " à partir de %.*s"
+
+#: src/login.c:1303
+msgid "Starting rad_login\n"
+msgstr "Démarrage de rad_login\n"
+
+#: src/mkpasswd.c:49
+#, c-format
+msgid "%s: no DBM database on system - no action performed\n"
+msgstr "%s : pas de base de données DBM sur le système - aucune action prise\n"
+
+#: src/mkpasswd.c:245 src/mkpasswd.c:249
+#, c-format
+msgid "%s: cannot overwrite file %s\n"
+msgstr "%s : impossible d'écraser le fichier %s\n"
+
+#: src/mkpasswd.c:263
+#, c-format
+msgid "%s: cannot open DBM files for %s\n"
+msgstr "%s : impossible d'ouvrir les fichiers DBM pour %s\n"
+
+#: src/mkpasswd.c:296
+#, c-format
+msgid "%s: the beginning with "
+msgstr ""
+
+#: src/mkpasswd.c:321
+#, c-format
+msgid "%s: error parsing line \"%s\"\n"
+msgstr "%s : erreur lors l'analyse de la ligne \"%s\"\n"
+
+#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332
+msgid "adding record for name "
+msgstr ""
+
+#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349
+#, c-format
+msgid "%s: error adding record for "
+msgstr ""
+
+#: src/mkpasswd.c:367
+#, c-format
+msgid "added %d entries, longest was %d\n"
+msgstr "%d entrées ajoutées, la plus longue fut %d\n"
+
+#: src/mkpasswd.c:382
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"
+msgstr "Usage : %s [ -vf ] [ -p|g|sp|sg ] fichier\n"
+
+#: src/mkpasswd.c:384
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n"
+msgstr "Usage : %s [ -vf ] [ -p|g|sp ] fichier\n"
+
+#: src/mkpasswd.c:387
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g ] file\n"
+msgstr "Usage : %s [ -vf ] [ -p|g ] fichier\n"
+
+#: src/newgrp.c:66
+msgid "usage: newgrp [ - ] [ group ]\n"
+msgstr "Usage : newgrp [ - ] [ groupe ]\n"
+
+#: src/newgrp.c:68
+#, fuzzy
+msgid "usage: sg group [[-c] command ]\n"
+msgstr "Usage : sg groupe [ commande ]\n"
+
+#: src/newgrp.c:125
+#, c-format
+msgid "unknown uid: %d\n"
+msgstr "uid inconnue : %d\n"
+
+#: src/newgrp.c:201
+#, c-format
+msgid "unknown gid: %ld\n"
+msgstr "gid inconnu : %ld\n"
+
+#: src/newgrp.c:245
+#, c-format
+msgid "unknown gid: %d\n"
+msgstr "gid inconnu : %d\n"
+
+#: src/newgrp.c:323 src/newgrp.c:332
+msgid "Sorry.\n"
+msgstr "Désolé ;-)\n"
+
+#: src/newgrp.c:364
+msgid "too many groups\n"
+msgstr "trop de groupes\n"
+
+#: src/newusers.c:76
+#, c-format
+msgid "Usage: %s [ input ]\n"
+msgstr "Usage : %s [ entrée ] \n"
+
+#: src/newusers.c:364
+#, c-format
+msgid "%s: can't lock /etc/passwd.\n"
+msgstr "%s : impossible de vérouiller /etc/passwd.\n"
+
+#: src/newusers.c:375
+#, c-format
+msgid "%s: can't lock files, try again later\n"
+msgstr "%s : impossible de vérouiller les fichiers, essayez plus tard\n"
+
+#: src/newusers.c:390
+#, c-format
+msgid "%s: can't open files\n"
+msgstr "%s : impossible d'ouvrir les fichiers\n"
+
+#: src/newusers.c:435
+#, c-format
+msgid "%s: line %d: invalid line\n"
+msgstr "%s : ligne %d : ligne non valide\n"
+
+#: src/newusers.c:453
+#, c-format
+msgid "%s: line %d: can't create GID\n"
+msgstr "%s : ligne %d : impossible de créer le GID\n"
+
+#: src/newusers.c:469
+#, c-format
+msgid "%s: line %d: can't create UID\n"
+msgstr "%s : ligne %d : impossible de créer le GID\n"
+
+#: src/newusers.c:481
+#, c-format
+msgid "%s: line %d: cannot find user %s\n"
+msgstr "%s : ligne %d : impossible de trouver l'utilisateur %s\n"
+
+#: src/newusers.c:489
+#, c-format
+msgid "%s: line %d: can't update password\n"
+msgstr "%s : ligne %d : impossible de mettre le mot de passe à jour\n"
+
+#: src/newusers.c:506
+#, c-format
+msgid "%s: line %d: mkdir failed\n"
+msgstr "%s : ligne %d : échec de mkdir\n"
+
+#: src/newusers.c:510
+#, c-format
+msgid "%s: line %d: chown failed\n"
+msgstr "%s : ligne %d : échec de chown\n"
+
+#: src/newusers.c:519
+#, c-format
+msgid "%s: line %d: can't update entry\n"
+msgstr "%s : ligne %d : impossible de mettre l'entrée à jour\n"
+
+#: src/newusers.c:550
+#, c-format
+msgid "%s: error updating files\n"
+msgstr "%s : erreur lors de la mise à jour des fichiers\n"
+
+#: src/passwd.c:239
+#, c-format
+msgid "usage: %s [ -f | -s ] [ name ]\n"
+msgstr "Usage : %s [ -f | -s ] [ nom ]\n"
+
+#: src/passwd.c:242
+#, c-format
+msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"
+msgstr " %s [ -x max ] [ -n min ] [ -w avert ] [ -i inact ] nom\n"
+
+#: src/passwd.c:245
+#, c-format
+msgid " %s { -l | -u | -d | -S | -e } name\n"
+msgstr " %s { -l | -u | -d | -S | -e } nom\n"
+
+#: src/passwd.c:347
+#, c-format
+msgid "User %s has a TCFS key, his old password is required.\n"
+msgstr ""
+"L'utilisateur %s a une clé TCFS, son ancien mot de passe est nécessaire.\n"
+
+#: src/passwd.c:348
+msgid "You can use -t option to force the change.\n"
+msgstr "Vous pouvez utiliser l'option -t pour forcer le changement.\n"
+
+#: src/passwd.c:354
+msgid "Old password: "
+msgstr "Ancien mot de passe : "
+
+#: src/passwd.c:361
+#, c-format
+msgid "Incorrect password for `%s'\n"
+msgstr "Mot de passe incorrect pour `%s'\n"
+
+#: src/passwd.c:374
+#, c-format
+msgid "Warning: user %s has a TCFS key.\n"
+msgstr "Avertissement : l'utilisateur %s a une clé TCFS.\n"
+
+#: src/passwd.c:392
+#, c-format
+msgid ""
+"Enter the new password (minimum of %d, maximum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"
+msgstr ""
+"Entrez le nouveau mot de passe (minimum de %d, maximum de %d\n"
+"caractères). Utilisez une combinaison de lettres en majuscule/minuscule\n"
+"et de nombres.\n"
+
+#: src/passwd.c:399
+msgid "New password: "
+msgstr "Nouveau mot de passe : "
+
+#: src/passwd.c:409
+msgid "Try again.\n"
+msgstr "Essaye encore...\n"
+
+#: src/passwd.c:418
+msgid ""
+"\n"
+"Warning: weak password (enter it again to use it anyway).\n"
+msgstr ""
+"\n"
+"Avertissement : mot de passe simpliste (tapez le à nouveau pour l'utiliser\n"
+"quand même).\n"
+
+#: src/passwd.c:427
+msgid "They don't match; try again.\n"
+msgstr "Ils ne sont pas identique; essaye encore...\n"
+
+#: src/passwd.c:512 src/passwd.c:528
+#, c-format
+msgid "The password for %s cannot be changed.\n"
+msgstr "Le mot de passe pour %s ne peut être changé.\n"
+
+#: src/passwd.c:556
+#, c-format
+msgid "Sorry, the password for %s cannot be changed yet.\n"
+msgstr "Désolé, le mot de passe pour %s ne peux pas encore être changé.\n"
+
+#: src/passwd.c:693
+#, c-format
+msgid "%s: out of memory\n"
+msgstr "%s : plus de mémoire\n"
+
+#: src/passwd.c:845
+msgid "Cannot lock the TCFS key database; try again later\n"
+msgstr ""
+"Impossible de vérouiller la base de données de clés TCFS; essayez à\n"
+"nouveau plus tard\n"
+
+#: src/passwd.c:851
+msgid "Cannot open the TCFS key database.\n"
+msgstr "Impossible d'ouvrir la base de clés TCFS.\n"
+
+#: src/passwd.c:857
+msgid "Error updating the TCFS key database.\n"
+msgstr "Erreur lors de la mise à jour de la base de clés TCFS.\n"
+
+#: src/passwd.c:862
+msgid "Cannot commit TCFS changes.\n"
+msgstr "Impossible de valider les changements TCFS.\n"
+
+#: src/passwd.c:1069
+#, c-format
+msgid "%s: Cannot execute %s"
+msgstr "%s : Impossible d'exécuter %s"
+
+#: src/passwd.c:1176
+#, c-format
+msgid "%s: repository %s not supported\n"
+msgstr ""
+
+#: src/passwd.c:1263
+#, c-format
+msgid "%s: Permission denied\n"
+msgstr "%s : Permission refusée\n"
+
+#: src/passwd.c:1287
+#, c-format
+msgid "You may not change the password for %s.\n"
+msgstr "Vous ne pouvez pas changer le mot de passe de %s.\n"
+
+#: src/passwd.c:1352
+#, c-format
+msgid "Changing password for %s\n"
+msgstr "Changement du mot de passe de %s\n"
+
+#: src/passwd.c:1356
+#, c-format
+msgid "The password for %s is unchanged.\n"
+msgstr "Le mot de passe pour %s est inchangé.\n"
+
+#: src/passwd.c:1412
+msgid "Password changed.\n"
+msgstr "Mot de passe changé.\n"
+
+#: src/pwck.c:98
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"
+msgstr "Usage : %s [ -qr ] [ passwd [ shadow ] ]\n"
+
+#: src/pwck.c:100
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd ]\n"
+msgstr "Usage : %s [ -qr ] [ passwd ]\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:285
+msgid "invalid password file entry\n"
+msgstr "entrée non valide dans le fichier password\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:347
+msgid "duplicate password entry\n"
+msgstr "entrée dupliquée dans password\n"
+
+#: src/pwck.c:363
+#, c-format
+msgid "invalid user name `%s'\n"
+msgstr "nom d'utilisateur `%s' non valide\n"
+
+#: src/pwck.c:373
+#, c-format
+msgid "user %s: bad UID (%d)\n"
+msgstr "utilisateur %s : mauvais UID (%d)\n"
+
+#.
+#. * No primary group, just give a warning
+#.
+#: src/pwck.c:388
+#, c-format
+msgid "user %s: no group %d\n"
+msgstr "utilisateur %s : aucun groupe %d\n"
+
+#.
+#. * Home directory doesn't exist, give a warning
+#.
+#: src/pwck.c:403
+#, c-format
+msgid "user %s: directory %s does not exist\n"
+msgstr "utilisateur %s : le répertoire %s n'existe pas\n"
+
+#.
+#. * Login shell doesn't exist, give a warning
+#.
+#: src/pwck.c:418
+#, c-format
+msgid "user %s: program %s does not exist\n"
+msgstr "utilisateur %s : le programme %s n'existe pas\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:454
+msgid "invalid shadow password file entry\n"
+msgstr "entrée shadow password non valide\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:516
+msgid "duplicate shadow password entry\n"
+msgstr "entrée shadow password dupliquée\n"
+
+#.
+#. * Tell the user this entry has no matching
+#. * /etc/passwd entry and ask them to delete it.
+#.
+#: src/pwck.c:540
+msgid "no matching password file entry\n"
+msgstr "aucune entrée correspondante dans le fichier password\n"
+
+#: src/pwck.c:557
+#, c-format
+msgid "user %s: last password change in the future\n"
+msgstr ""
+"utilisateur %s : date du dernier changement de mot de passe dans le futur\n"
+
+#: src/pwconv.c:94 src/pwunconv.c:108
+#, c-format
+msgid "%s: can't lock passwd file\n"
+msgstr "%s : impossible de vérouiller le fichier passwd\n"
+
+#: src/pwconv.c:99 src/pwunconv.c:113
+#, c-format
+msgid "%s: can't open passwd file\n"
+msgstr "%s : impossible d'ouvrir le fichier passwd\n"
+
+#: src/pwconv.c:126
+#, c-format
+msgid "%s: can't remove shadow entry for %s\n"
+msgstr "%s : impossible d'enlever l'entrée shadow pour %s\n"
+
+#: src/pwconv.c:169
+#, c-format
+msgid "%s: can't update passwd entry for %s\n"
+msgstr "%s : impossible de mettre à jour le mot de passe de %s\n"
+
+#: src/pwconv.c:176
+#, c-format
+msgid "%s: can't update shadow file\n"
+msgstr "%s : impossible de mettre à jour le fichier shadow\n"
+
+#: src/pwconv.c:180
+#, c-format
+msgid "%s: can't update passwd file\n"
+msgstr "%s : impossible de mettre à jour le fichier passwd\n"
+
+#: src/pwunconv.c:62
+#, c-format
+msgid "%s: Shadow passwords are not configured.\n"
+msgstr "%s : Les mots de passe shadow ne sont pas configurés.\n"
+
+#: src/pwunconv.c:171
+#, c-format
+msgid "%s: can't update entry for user %s\n"
+msgstr "%s : impossible de mettre à jour l'entrée %s\n"
+
+#: src/pwunconv.c:188
+#, c-format
+msgid "%s: can't delete shadow password file\n"
+msgstr "%s : impossible d'effacer le fichier shadow\n"
+
+#: src/su.c:140
+msgid "Sorry."
+msgstr "Désolé ;-)"
+
+#: src/su.c:222
+#, c-format
+msgid "%s: must be run from a terminal\n"
+msgstr "%s : doit être lancé à partir d'un terminal\n"
+
+#: src/su.c:311
+#, c-format
+msgid "%s: pam_start: error %d\n"
+msgstr "%s : pam_start : erreur %d\n"
+
+#: src/su.c:337
+#, c-format
+msgid "Unknown id: %s\n"
+msgstr "ID inconnue : %s\n"
+
+#. access denied (-1) or unexpected value
+#: src/su.c:372 src/su.c:387
+#, fuzzy, c-format
+msgid "You are not authorized to su %s\n"
+msgstr "Vous n'êtes pas authorisés "
+
+#. require own password
+#: src/su.c:383
+msgid "(Enter your own password.)"
+msgstr "(Entrez votre propre mot de passe.)"
+
+#: src/su.c:404
+#, c-format
+msgid "%s: permission denied (shell).\n"
+msgstr "%s : permission refusée (shell).\n"
+
+#: src/su.c:428
+#, c-format
+msgid ""
+"%s: %s\n"
+"(Ignored)\n"
+msgstr ""
+"%s: %s\n"
+"(Ignoré)\n"
+
+#: src/su.c:628
+msgid "No shell\n"
+msgstr "Pas de shell\n"
+
+#. must be a password file!
+#: src/sulogin.c:136
+msgid "No password file\n"
+msgstr "Pas de fichier de mot de passe\n"
+
+#.
+#. * Fail secure
+#.
+#: src/sulogin.c:178
+msgid "No password entry for 'root'\n"
+msgstr "Pas d'entrée pour le mot de passe de 'root'\n"
+
+#.
+#. * Here we prompt for the root password, or if no password is
+#. * given we just exit.
+#.
+#. get a password for root
+#: src/sulogin.c:192
+msgid ""
+"\n"
+"Type control-d to proceed with normal startup,\n"
+"(or give root password for system maintenance):"
+msgstr ""
+"\n"
+"Tapez control-d pour procéder au démarrage normal,\n"
+"(ou donnez le mot de passe de root pour la maintenance) : "
+
+#. make new environment active
+#: src/sulogin.c:241
+msgid "Entering System Maintenance Mode\n"
+msgstr "Entrée du système en mode maintenance\n"
+
+#: src/useradd.c:243
+#, c-format
+msgid "%s: rebuild the group database\n"
+msgstr "%s : reconstruction de la base de données des groupes\n"
+
+#: src/useradd.c:250
+#, c-format
+msgid "%s: rebuild the shadow group database\n"
+msgstr "%s : reconstruction de la base de données des groupes shadow\n"
+
+#: src/useradd.c:287 src/usermod.c:967
+#, c-format
+msgid "%s: invalid numeric argument `%s'\n"
+msgstr "%s : argument numérique `%s' non valide\n"
+
+#: src/useradd.c:343
+#, c-format
+msgid "%s: unknown gid %s\n"
+msgstr "%s : gid %s inconnu\n"
+
+#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254
+#: src/usermod.c:1098
+#, c-format
+msgid "%s: unknown group %s\n"
+msgstr "%s : groupe %s inconnu\n"
+
+#: src/useradd.c:418
+#, c-format
+msgid "group=%s,%ld basedir=%s skel=%s\n"
+msgstr "group=%s,%ld rép_base=%s skel=%s\n"
+
+#: src/useradd.c:421
+#, c-format
+msgid "shell=%s "
+msgstr "shell=%s "
+
+#: src/useradd.c:423
+#, c-format
+msgid "inactive=%ld expire=%s"
+msgstr "inactif=%ld expire=%s"
+
+#: src/useradd.c:427
+#, c-format
+msgid "GROUP=%ld\n"
+msgstr "GROUP=%ld\n"
+
+#: src/useradd.c:428
+#, c-format
+msgid "HOME=%s\n"
+msgstr "HOME=%s\n"
+
+#: src/useradd.c:430
+#, c-format
+msgid "INACTIVE=%ld\n"
+msgstr "INACTIVE=%ld\n"
+
+#: src/useradd.c:431
+#, c-format
+msgid "EXPIRE=%s\n"
+msgstr "EXPIRE=%s\n"
+
+#: src/useradd.c:433
+#, c-format
+msgid "SHELL=%s\n"
+msgstr "SHELL=%s\n"
+
+#: src/useradd.c:434
+#, c-format
+msgid "SKEL=%s\n"
+msgstr "SKEL=%s\n"
+
+#: src/useradd.c:470
+#, c-format
+msgid "%s: cannot create new defaults file\n"
+msgstr "%s : impossible de créer un nouveau fichier de défauts\n"
+
+#: src/useradd.c:564 src/useradd.c:575
+#, c-format
+msgid "%s: rename: %s"
+msgstr "%s : rename : %s"
+
+#: src/useradd.c:662 src/usermod.c:274
+#, c-format
+msgid "%s: group `%s' is a NIS group.\n"
+msgstr "%s : le groupe `%s' est un groupe NIS.\n"
+
+#: src/useradd.c:670 src/usermod.c:282
+#, c-format
+msgid "%s: too many groups specified (max %d).\n"
+msgstr "%s : trop de groupes spécifiés (max %d).\n"
+
+#: src/useradd.c:702 src/usermod.c:314
+#, c-format
+msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"
+msgstr "Usage : %s\t[-u uid [-o]] [-g groupe] [-G groupe,...] \n"
+
+#: src/useradd.c:705
+msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n"
+msgstr "\t\t[-d home] [-s shell] [-c commentaire] [-m [-k template]]\n"
+
+#: src/useradd.c:708 src/usermod.c:320
+msgid "[-f inactive] [-e expire ] "
+msgstr "[-f inactif] [-e expire ] "
+
+#: src/useradd.c:711
+msgid "[-A program] "
+msgstr "[-A program] "
+
+#: src/useradd.c:713
+msgid "[-p passwd] name\n"
+msgstr "[-p mot-de-passe] nom\n"
+
+#: src/useradd.c:715
+#, c-format
+msgid " %s\t-D [-g group] [-b base] [-s shell]\n"
+msgstr " %s\t-D [-g groupe] [-b base] [-s shell]\n"
+
+#: src/useradd.c:718
+msgid "\t\t[-f inactive] [-e expire ]\n"
+msgstr "\t\t[-f inactif] [-e expire ]\n"
+
+#: src/useradd.c:815 src/usermod.c:472
+#, c-format
+msgid "%s: error locking group file\n"
+msgstr "%s : erreur lors du vérouillage du fichier de groupe\n"
+
+#: src/useradd.c:819 src/usermod.c:477
+#, c-format
+msgid "%s: error opening group file\n"
+msgstr "%s : erreur lors d'ouverture du fichier de groupe\n"
+
+#: src/useradd.c:824 src/usermod.c:584
+#, c-format
+msgid "%s: error locking shadow group file\n"
+msgstr "%s : erreur lors du vérouillage du fichier shadow group\n"
+
+#: src/useradd.c:829 src/usermod.c:590
+#, c-format
+msgid "%s: error opening shadow group file\n"
+msgstr "%s : erreur lors de l'ouverture du fichier shadow group\n"
+
+#: src/useradd.c:1001
+#, c-format
+msgid "%s: uid %d is not unique\n"
+msgstr "%s : l'uid %d n'est pas unique\n"
+
+#: src/useradd.c:1031
+#, c-format
+msgid "%s: can't get unique uid\n"
+msgstr "%s : impossible d'obtenir un uid unique\n"
+
+#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057
+#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157
+#, c-format
+msgid "%s: invalid field `%s'\n"
+msgstr "%s : champs `%s' non valide\n"
+
+#: src/useradd.c:1153
+#, c-format
+msgid "%s: invalid base directory `%s'\n"
+msgstr "%s : répertoire de base non valide `%s'\n"
+
+#: src/useradd.c:1163
+#, c-format
+msgid "%s: invalid comment `%s'\n"
+msgstr "%s : commentaire `%s' non valide\n"
+
+#: src/useradd.c:1173
+#, c-format
+msgid "%s: invalid home directory `%s'\n"
+msgstr "%s : répertoire personnel `%s' non valide\n"
+
+#: src/useradd.c:1191 src/usermod.c:1080
+#, c-format
+msgid "%s: invalid date `%s'\n"
+msgstr "%s : date `%s' non valide\n"
+
+#: src/useradd.c:1203
+#, c-format
+msgid "%s: shadow passwords required for -e\n"
+msgstr "%s : mots de passe shadow nécessaires pour -e\n"
+
+#: src/useradd.c:1218
+#, c-format
+msgid "%s: shadow passwords required for -f\n"
+msgstr "%s : mots de passe shadow nécessaires pour -f\n"
+
+#: src/useradd.c:1292
+#, c-format
+msgid "%s: invalid shell `%s'\n"
+msgstr "%s : shell `%s' non valide\n"
+
+#: src/useradd.c:1333
+#, c-format
+msgid "%s: invalid user name `%s'\n"
+msgstr "%s : nom d'utilisateur `%s' non valide\n"
+
+#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225
+#, c-format
+msgid "%s: cannot rewrite password file\n"
+msgstr "%s : impossible de reécrire le fichier de mots de passe\n"
+
+#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230
+#, c-format
+msgid "%s: cannot rewrite shadow password file\n"
+msgstr "%s : impossible de reécrire le fichier shadow\n"
+
+#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265
+#, c-format
+msgid "%s: unable to lock password file\n"
+msgstr "%s : impossible de vérouiller le fichier de mots de passe\n"
+
+#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269
+#, c-format
+msgid "%s: unable to open password file\n"
+msgstr "%s : impossible d'ouvrir le fichier de mots de passe\n"
+
+#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274
+#, c-format
+msgid "%s: cannot lock shadow password file\n"
+msgstr "%s : impossible de vérouiller le fichier de mots de passe\n"
+
+#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279
+#, c-format
+msgid "%s: cannot open shadow password file\n"
+msgstr "%s : impossible d'ouvrir le fichier shadow\n"
+
+#: src/useradd.c:1529 src/usermod.c:1366
+#, c-format
+msgid "%s: error adding authentication method\n"
+msgstr "%s : erreur lors de l'ajout de la méthode d'authentification\n"
+
+#: src/useradd.c:1552
+#, c-format
+msgid "%s: error adding new password entry\n"
+msgstr "%s : erreur lors de l'ajout de la nouvelle entrée\n"
+
+#: src/useradd.c:1567
+#, c-format
+msgid "%s: error updating password dbm entry\n"
+msgstr "%s : erreur lors de la mise à jour de l'entrée dbm\n"
+
+#: src/useradd.c:1583 src/usermod.c:1425
+#, c-format
+msgid "%s: error adding new shadow password entry\n"
+msgstr "%s : erreur lors de l'ajout de la nouvelle entrée shadow\n"
+
+#: src/useradd.c:1599 src/usermod.c:1440
+#, c-format
+msgid "%s: error updating shadow passwd dbm entry\n"
+msgstr "%s : erreur lors de la mise à jour de l'entrée shadow passwd dbm\n"
+
+#: src/useradd.c:1631
+#, c-format
+msgid "%s: cannot create directory %s\n"
+msgstr "%s : impossible de créer le répertoire %s\n"
+
+#: src/useradd.c:1708 src/usermod.c:1203
+#, c-format
+msgid "%s: user %s exists\n"
+msgstr "%s : l'utilisateur %s existe\n"
+
+#: src/useradd.c:1738
+#, c-format
+msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n"
+msgstr ""
+"%s : avertissement : CREATE_HOME non supporté, utilisez -m à la place.\n"
+
+#: src/userdel.c:127
+#, c-format
+msgid "usage: %s [-r] name\n"
+msgstr "Usage : %s [-r] nom\n"
+
+#: src/userdel.c:178 src/userdel.c:260
+#, c-format
+msgid "%s: error updating group entry\n"
+msgstr "%s : erreur lors de la mise à jour de l'entrée group\n"
+
+#: src/userdel.c:188 src/userdel.c:269
+#, c-format
+msgid "%s: cannot update dbm group entry\n"
+msgstr "%s : impossible de mettre à jour l'entrée dbm group\n"
+
+#: src/userdel.c:215
+#, fuzzy, c-format
+msgid "%s: cannot remove dbm group entry\n"
+msgstr "%s : impossible de mettre à jour l'entrée dbm group\n"
+
+#: src/userdel.c:300
+#, c-format
+msgid "%s: cannot rewrite TCFS key file\n"
+msgstr "%s : impossible de reécrire le fichier de clés TCFS\n"
+
+#: src/userdel.c:380
+#, c-format
+msgid "%s: cannot lock TCFS key file\n"
+msgstr "%s : impossible de vérouiller le fichier de clés TCFS\n"
+
+#: src/userdel.c:384
+#, c-format
+msgid "%s: cannot open TCFS key file\n"
+msgstr "%s : impossible d'ouvrir le fichier de clés TCFS\n"
+
+#: src/userdel.c:393
+#, c-format
+msgid "%s: cannot open group file\n"
+msgstr "%s : impossible d'ouvrir le fichier group\n"
+
+#: src/userdel.c:403
+#, c-format
+msgid "%s: cannot open shadow group file\n"
+msgstr "%s : impossible d'ouvrir le fichier shadow group\n"
+
+#: src/userdel.c:434 src/userdel.c:449
+#, c-format
+msgid "%s: error deleting authentication\n"
+msgstr "%s : erreur lors de l'effacement de l'authentification\n"
+
+#: src/userdel.c:458
+#, c-format
+msgid "%s: error deleting password entry\n"
+msgstr "%s : erreur lors de la suppression de l'entrée dans /etc/passwd\n"
+
+#: src/userdel.c:461
+#, c-format
+msgid "%s: error deleting shadow password entry\n"
+msgstr "%s : erreur lors de la suppression de l'entrée dans /etc/shadow\n"
+
+#: src/userdel.c:470
+#, c-format
+msgid "%s: error deleting TCFS entry\n"
+msgstr "%s : erreur lors de l'effacement de l'entrée TCFS\n"
+
+#: src/userdel.c:483
+#, c-format
+msgid "%s: error deleting password dbm entry\n"
+msgstr "%s : erreur lors de l'effacement de l'entrée dbm du mot de passe\n"
+
+#: src/userdel.c:502
+#, c-format
+msgid "%s: error deleting shadow passwd dbm entry\n"
+msgstr "%s : erreur lors de l'effacement de l'entrée shadow passwd dbm\n"
+
+#: src/userdel.c:543
+#, c-format
+msgid "%s: user %s is currently logged in\n"
+msgstr "%s : l'utilisateur %s est connecté\n"
+
+#: src/userdel.c:660
+#, c-format
+msgid "%s: warning: %s not owned by %s, not removing\n"
+msgstr "%s : avertissement : %s n'appartient pas à %s, non enlevé\n"
+
+#: src/userdel.c:666
+#, c-format
+msgid "%s: warning: can't remove "
+msgstr "%s : impossible d'enlever "
+
+#: src/userdel.c:741 src/usermod.c:994
+#, c-format
+msgid "%s: user %s does not exist\n"
+msgstr "%s : l'utilisateur %s n'existe pas\n"
+
+#: src/userdel.c:755 src/usermod.c:1010
+#, c-format
+msgid "%s: user %s is a NIS user\n"
+msgstr "%s : le compte %s est un compte NIS\n"
+
+#: src/userdel.c:792
+#, c-format
+msgid "%s: %s not owned by %s, not removing\n"
+msgstr "%s : %s n'appartient pas à %s, non enlevé\n"
+
+#: src/userdel.c:815
+#, c-format
+msgid "%s: not removing directory %s (would remove home of user %s)\n"
+msgstr ""
+"%s : répertoire %s non enlevé (cela enléverait le répertoire personnel de "
+"%s)\n"
+
+#: src/userdel.c:828
+#, c-format
+msgid "%s: error removing directory %s\n"
+msgstr "%s : erreur lors de l'effacement du répertoire %s\n"
+
+#: src/usermod.c:317
+msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"
+msgstr "\t\t[-d home [-m]] [-s shell] [-c commentaire] [-l nouveau_nom]\n"
+
+#: src/usermod.c:323
+msgid "[-A {DEFAULT|program},... ] "
+msgstr "[-A {DÉFAUT|programme},... ] "
+
+#: src/usermod.c:325
+#, fuzzy
+msgid "[-p passwd] [-L|-U] name\n"
+msgstr "[-p mot-de-passe] nom\n"
+
+#: src/usermod.c:504
+#, c-format
+msgid "%s: out of memory in update_group\n"
+msgstr "%s : plus de mémoire pour update_group\n"
+
+#: src/usermod.c:627
+#, c-format
+msgid "%s: out of memory in update_gshadow\n"
+msgstr "%s : plus de mémoire pour update_gshadow\n"
+
+#: src/usermod.c:1180
+#, c-format
+msgid "%s: no flags given\n"
+msgstr "%s : aucun drapeau donné\n"
+
+#: src/usermod.c:1187
+#, c-format
+msgid "%s: shadow passwords required for -e and -f\n"
+msgstr "%s : mots de passe shadow nécessaires pour -e ou -f\n"
+
+#: src/usermod.c:1208
+#, c-format
+msgid "%s: uid %ld is not unique\n"
+msgstr "%s : l'uid %ld n'est pas unique\n"
+
+#: src/usermod.c:1356
+#, c-format
+msgid "%s: error deleting authentication method\n"
+msgstr "%s : erreur lors de l'effacement de la méthode d'authentification\n"
+
+#: src/usermod.c:1376
+#, c-format
+msgid "%s: error changing authentication method\n"
+msgstr "%s : erreur lors du changement de la méthode d'authentification\n"
+
+#: src/usermod.c:1393
+#, c-format
+msgid "%s: error changing password entry\n"
+msgstr "%s : erreur lors du changement de l'entrée dans /etc/passwd\n"
+
+#: src/usermod.c:1399
+#, c-format
+msgid "%s: error removing password entry\n"
+msgstr "%s : erreur lors de l'effacement du mot de passe\n"
+
+#: src/usermod.c:1407
+#, c-format
+msgid "%s: error adding password dbm entry\n"
+msgstr ""
+
+#: src/usermod.c:1414
+#, c-format
+msgid "%s: error removing passwd dbm entry\n"
+msgstr ""
+
+#: src/usermod.c:1431
+#, c-format
+msgid "%s: error removing shadow password entry\n"
+msgstr ""
+
+#: src/usermod.c:1446
+#, c-format
+msgid "%s: error removing shadow passwd dbm entry\n"
+msgstr ""
+
+#: src/usermod.c:1477
+#, c-format
+msgid "%s: directory %s exists\n"
+msgstr "%s : le répertoire %s existe\n"
+
+#: src/usermod.c:1484
+#, c-format
+msgid "%s: can't create %s\n"
+msgstr "%s : impossible de créer %s\n"
+
+#: src/usermod.c:1490
+#, c-format
+msgid "%s: can't chown %s\n"
+msgstr "%s : impossible de changer le propriètaire de %s\n"
+
+#: src/usermod.c:1506
+#, c-format
+msgid "%s: cannot rename directory %s to %s\n"
+msgstr "%s : impossible de renommer le répertoire %s en %s\n"
+
+#. better leave it alone
+#: src/usermod.c:1603
+#, c-format
+msgid "%s: warning: %s not owned by %s\n"
+msgstr "%s : avertissement : %s n'appartient pas à %s\n"
+
+#: src/usermod.c:1609
+msgid "failed to change mailbox owner"
+msgstr "échec du changement de propriètaire de la mailbox"
+
+#: src/usermod.c:1616
+msgid "failed to rename mailbox"
+msgstr "échec du renommage de la mailbox"
+
+#: src/vipw.c:102
+#, c-format
+msgid ""
+"\n"
+"%s: %s is unchanged\n"
+msgstr ""
+"\n"
+"%s : %s est inchangé\n"
+
+#: src/vipw.c:127
+msgid "Couldn't lock file"
+msgstr "Impossible de vérouiller le fichier"
+
+#: src/vipw.c:134
+msgid "Couldn't make backup"
+msgstr "Impossible de faire une sauvegarde"
+
+#: src/vipw.c:187
+#, c-format
+msgid "%s: can't restore %s: %s (your changes are in %s)\n"
+msgstr "%s : impossible de restaurer %s : %s (vos changements sont dans %s)\n"
+
+#: src/vipw.c:226
+msgid ""
+"Usage:\n"
+"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n"
+"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n"
+msgstr ""
+"Usage :\n"
+"`vipw' édite /etc/passwd `vipw -s' édite /etc/shadow\n"
+"`vigr' édite /etc/group `vigr -s' édite /etc/gshadow\n"
diff --git a/current/po/pl.gmo b/current/po/pl.gmo
new file mode 100644
index 00000000..e4ee08ef
--- /dev/null
+++ b/current/po/pl.gmo
Binary files differ
diff --git a/current/po/pl.po b/current/po/pl.po
new file mode 100644
index 00000000..94fcd677
--- /dev/null
+++ b/current/po/pl.po
@@ -0,0 +1,2414 @@
+# shadow.pot Polish translation.
+# Copyright (C) 1999 Free Software Foundation, Inc.
+# Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>, 1999.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: shadow-981228\n"
+"POT-Creation-Date: 2000-09-02 20:40+0200\n"
+"PO-Revision-Date: 1999-03-02 22:29+01:00\n"
+"Last-Translator: Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>\n"
+"Language-Team: PL <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmisc/addgrps.c:60
+#, c-format
+msgid "Warning: unknown group %s\n"
+msgstr "Ostrze¿enie: nieznana grupa %s\n"
+
+#: libmisc/addgrps.c:71
+msgid "Warning: too many groups\n"
+msgstr "Ostrze¿enie: zbyt wiele grup\n"
+
+#: libmisc/age.c:104
+msgid "Your password has expired."
+msgstr "Twoje has³o straci³o wa¿no¶æ."
+
+#: libmisc/age.c:107
+msgid "Your password is inactive."
+msgstr "Twoje has³o jest nieaktywne."
+
+#: libmisc/age.c:110
+msgid "Your login has expired."
+msgstr "Twoje konto straci³o wa¿no¶æ."
+
+#: libmisc/age.c:127
+msgid " Contact the system administrator.\n"
+msgstr " Skontaktuj siê z administratorem systemu.\n"
+
+#: libmisc/age.c:130
+msgid " Choose a new password.\n"
+msgstr " Wybierz nowe has³o.\n"
+
+#: libmisc/age.c:228
+#, c-format
+msgid "Your password will expire in %ld days.\n"
+msgstr "Twoje has³o straci wa¿no¶æ w ci±gu %ld dni.\n"
+
+#: libmisc/age.c:230
+msgid "Your password will expire tomorrow.\n"
+msgstr "Jutro twoje has³o straci wa¿no¶æ.\n"
+
+#: libmisc/age.c:232
+msgid "Your password will expire today.\n"
+msgstr "Dzi¶ twoje has³o straci wa¿no¶æ.\n"
+
+#: libmisc/chowntty.c:110
+#, c-format
+msgid "Unable to change tty %s"
+msgstr "Nie mo¿na zmieniæ tty %s"
+
+#: libmisc/env.c:160
+msgid "Environment overflow\n"
+msgstr "Przepe³nienie ¶rodowiska\n"
+
+#: libmisc/env.c:200
+#, c-format
+msgid "You may not change $%s\n"
+msgstr "Nie mo¿esz zmieniaæ $%s\n"
+
+#: libmisc/failure.c:238
+#, c-format
+msgid "%d %s since last login. Last was %s on %s.\n"
+msgstr ""
+"%d %s od ostatniego logowania. Ostatnie logowanie: dnia %s na terminalu "
+"%s.\n"
+
+#: libmisc/failure.c:239
+msgid "failures"
+msgstr "niepowodzenia"
+
+#: libmisc/failure.c:239
+msgid "failure"
+msgstr "niepowodzenie"
+
+#: libmisc/limits.c:397
+msgid "Too many logins.\n"
+msgstr "Zbyt wiele otwartych sesji.\n"
+
+#: libmisc/login_desrpc.c:63
+#, c-format
+msgid "Password does not decrypt secret key for %s.\n"
+msgstr "Tym has³em nie mo¿na zdeszyfrowaæ tajnego klucza dla %s.\n"
+
+#: libmisc/login_desrpc.c:69
+#, c-format
+msgid "Could not set %s's secret key: is the keyserv daemon running?\n"
+msgstr "Nie mogê ustawiæ tajnego klucza dla %s: czy serwer kluczy dzia³a?\n"
+
+#: libmisc/mail.c:62 libmisc/mail.c:77
+msgid "You have new mail."
+msgstr "Masz now± pocztê."
+
+#: libmisc/mail.c:73
+msgid "No mail."
+msgstr "Nie masz poczty."
+
+#: libmisc/mail.c:75
+msgid "You have mail."
+msgstr "Masz pocztê."
+
+#: libmisc/obscure.c:281 src/passwd.c:309
+#, c-format
+msgid "Bad password: %s. "
+msgstr "Z³e has³o: %s. "
+
+#: libmisc/pam_pass.c:42
+#, c-format
+msgid "passwd: pam_start() failed, error %d\n"
+msgstr "passwd: pam_start() nie powiod³o siê, b³±d %d\n"
+
+#: libmisc/pam_pass.c:49
+#, c-format
+msgid "passwd: %s\n"
+msgstr "passwd: %s\n"
+
+#: libmisc/setupenv.c:205
+#, c-format
+msgid "Unable to cd to \"%s\"\n"
+msgstr "Nie mogê zmieniæ katalogu na \"%s\"\n"
+
+#: libmisc/setupenv.c:213
+msgid "No directory, logging in with HOME=/"
+msgstr "Brak katalogu, logujê z HOME=/"
+
+#: libmisc/shell.c:78
+#, c-format
+msgid "Executing shell %s\n"
+msgstr "Uruchamiam pow³okê %s\n"
+
+#.
+#. * Obviously something is really wrong - I can't figure out
+#. * how to execute this stupid shell, so I might as well give
+#. * up in disgust ...
+#.
+#: libmisc/shell.c:122
+#, c-format
+msgid "Cannot execute %s"
+msgstr "Nie mogê uruchomiæ %s"
+
+#: libmisc/suauth.c:99
+msgid "Access to su to that account DENIED.\n"
+msgstr "Dostêp do polecenia su z tego konta ZABRONIONY.\n"
+
+#: libmisc/suauth.c:106
+msgid "Password authentication bypassed.\n"
+msgstr "Uwierzytelnianie na podstawie has³a pominiête.\n"
+
+#: libmisc/suauth.c:113
+msgid "Please enter your OWN password as authentication.\n"
+msgstr "Proszê wpisz swoje W£ASNE has³o jako has³o uwierzytelniaj±ce.\n"
+
+#: libmisc/sub.c:61
+#, c-format
+msgid "Invalid root directory \"%s\"\n"
+msgstr "Nieprawid³owy katalog g³ówny \"%s\"\n"
+
+#: libmisc/sub.c:73
+#, c-format
+msgid "Can't change root directory to \"%s\"\n"
+msgstr "Nie mogê zmieniæ g³ównego katalogu na \"%s\"\n"
+
+#: libmisc/xmalloc.c:28
+#, c-format
+msgid "malloc(%d) failed\n"
+msgstr "malloc(%d) nie powiod³o siê\n"
+
+#: lib/dialchk.c:71
+msgid "Dialup Password: "
+msgstr "Has³o dostêpu modemowego: "
+
+#: lib/getdef.c:253
+msgid "Could not allocate space for config info.\n"
+msgstr "Nie mogê przydzieliæ miejsca dla informacji o konfiguracji.\n"
+
+#.
+#. * Item was never found.
+#.
+#: lib/getdef.c:307
+#, c-format
+msgid "configuration error - unknown item '%s' (notify administrator)\n"
+msgstr ""
+"b³±d w konfiguracji - nieznana pozycja '%s' (powiadom administratora)\n"
+
+#: lib/getdef.c:394
+#, c-format
+msgid "error - lookup '%s' failed\n"
+msgstr "b³±d - wyszukiwanie '%s' niepowiod³o siê\n"
+
+#: lib/getdef.c:402
+#, c-format
+msgid "%s not found\n"
+msgstr "%s nie znaleziony\n"
+
+#.
+#. * get the password from her, and set the salt for
+#. * the decryption from the group file.
+#.
+#: lib/pwauth.c:54 src/newgrp.c:305
+msgid "Password: "
+msgstr "Has³o: "
+
+#: lib/pwauth.c:56
+#, c-format
+msgid "%s's Password: "
+msgstr "Has³o u¿ytkownika %s: "
+
+#: lib/pwauth.c:270
+msgid "(Echo on) "
+msgstr ""
+
+#: lib/strerror.c:20
+#, c-format
+msgid "Unknown error %d"
+msgstr "Nieznany b³±d %d"
+
+#: src/chage.c:156
+#, c-format
+msgid ""
+"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n"
+" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"
+msgstr ""
+"U¿ycie: %s [ -l ] [ -m min_dni ] [ -M maks_dni ] [ -W ostrze¿ ]\n"
+" [ -I nieaktywne ] [ -E utrata_wa¿no¶ci ] [ -d ostatni_dzieñ ] u¿ytkownik\n"
+
+#: src/chage.c:158
+#, c-format
+msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"
+msgstr ""
+"U¿ycie: %s [ -l ] [ -m min_dni ] [ -M maks_dni ] [ -d ostatni_dzieñ ] "
+"u¿ytkownik\n"
+
+#: src/chage.c:193
+msgid ""
+"Enter the new value, or press return for the default\n"
+"\n"
+msgstr ""
+"Wpisz now± warto¶æ lub wci¶nij return by przyj±c warto¶æ domy¶ln±\n"
+"\n"
+
+#: src/chage.c:196
+msgid "Minimum Password Age"
+msgstr "Minimalny wiek has³a"
+
+#: src/chage.c:201
+msgid "Maximum Password Age"
+msgstr "Maksymalny wiek has³a"
+
+#: src/chage.c:207
+msgid "Last Password Change (YYYY-MM-DD)"
+msgstr "Ostatnia zmiana has³a (RRRR-MM-DD)"
+
+#: src/chage.c:216
+msgid "Password Expiration Warning"
+msgstr "Ostrze¿enie o utracie wa¿no¶ci has³a"
+
+#: src/chage.c:221
+msgid "Password Inactive"
+msgstr "Has³o nieaktywne"
+
+#: src/chage.c:227
+msgid "Account Expiration Date (YYYY-MM-DD)"
+msgstr "Data utraty wa¿no¶ci konta (RRRR-MM-DD)"
+
+#.
+#. * Start with the easy numbers - the number of days before the
+#. * password can be changed, the number of days after which the
+#. * password must be chaged, the number of days before the
+#. * password expires that the user is told, and the number of
+#. * days after the password expires that the account becomes
+#. * unusable.
+#.
+#: src/chage.c:281
+#, c-format
+msgid "Minimum:\t%ld\n"
+msgstr "Minimum:\t%ld\n"
+
+#: src/chage.c:282
+#, c-format
+msgid "Maximum:\t%ld\n"
+msgstr "Maksimim:\t%ld\n"
+
+#: src/chage.c:284
+#, c-format
+msgid "Warning:\t%ld\n"
+msgstr "Ostrze¿enie:\t%ld\n"
+
+#: src/chage.c:285
+#, c-format
+msgid "Inactive:\t%ld\n"
+msgstr "Nieaktywne:\t%ld\n"
+
+#.
+#. * The "last change" date is either "Never" or the date the
+#. * password was last modified. The date is the number of
+#. * days since 1/1/1970.
+#.
+#: src/chage.c:294
+msgid "Last Change:\t\t"
+msgstr "Ostatnia zmiana:\t\t"
+
+#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340
+msgid "Never\n"
+msgstr "Nigdy\n"
+
+#.
+#. * The password expiration date is determined from the last
+#. * change date plus the number of days the password is valid
+#. * for.
+#.
+#: src/chage.c:308
+msgid "Password Expires:\t"
+msgstr "Has³o traci wa¿no¶æ:\t"
+
+#.
+#. * The account becomes inactive if the password is expired
+#. * for more than "inactdays". The expiration date is calculated
+#. * and the number of inactive days is added. The resulting date
+#. * is when the active will be disabled.
+#.
+#: src/chage.c:324
+#, fuzzy
+msgid "Password Inactive:\t"
+msgstr "Has³o nieaktywne:\t"
+
+#.
+#. * The account will expire on the given date regardless of the
+#. * password expiring or not.
+#.
+#: src/chage.c:338
+#, fuzzy
+msgid "Account Expires:\t"
+msgstr "Has³o traci wa¿no¶æ:\t"
+
+#: src/chage.c:486
+#, c-format
+msgid "%s: do not include \"l\" with other flags\n"
+msgstr "%s: nie ³±cz \"l\" z innymi flagami\n"
+
+#: src/chage.c:498 src/chage.c:610 src/login.c:529
+#, c-format
+msgid "%s: permission denied\n"
+msgstr "%s: odmowa dostêpu\n"
+
+#: src/chage.c:510 src/chpasswd.c:120
+#, c-format
+msgid "%s: can't lock password file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z has³ami\n"
+
+#: src/chage.c:516 src/chpasswd.c:124
+#, c-format
+msgid "%s: can't open password file\n"
+msgstr "%s: nie mogê otworzyæ pliku z has³ami\n"
+
+#: src/chage.c:523
+#, c-format
+msgid "%s: unknown user: %s\n"
+msgstr "%s: nieznany u¿ytkownik: %s\n"
+
+#: src/chage.c:542
+#, c-format
+msgid "%s: can't lock shadow password file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n"
+
+#: src/chage.c:549
+#, c-format
+msgid "%s: can't open shadow password file\n"
+msgstr "%s: nie mogê otworzyæ pliku z ukrytymi has³ami\n"
+
+#: src/chage.c:631
+#, c-format
+msgid "Changing the aging information for %s\n"
+msgstr "Zmieniam informacjê o u¿ytkowniku %s\n"
+
+#: src/chage.c:633
+#, c-format
+msgid "%s: error changing fields\n"
+msgstr "%s: b³±d podczas zmieniania pól\n"
+
+#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183
+#, c-format
+msgid "%s: can't update password file\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku z has³ami\n"
+
+#: src/chage.c:690 src/pwunconv.c:178
+#, c-format
+msgid "%s: can't update shadow password file\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku z ukrytymi has³ami\n"
+
+#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409
+#: src/passwd.c:825 src/passwd.c:926
+msgid "Error updating the DBM password entry.\n"
+msgstr "B³±d podczas aktualizacki bazy hase³ DBM.\n"
+
+#: src/chage.c:771
+#, c-format
+msgid "%s: can't rewrite shadow password file\n"
+msgstr "%s: nie mogê przepisaæ pliku z ukrytymi has³ami\n"
+
+#: src/chage.c:785
+#, c-format
+msgid "%s: can't rewrite password file\n"
+msgstr "%s: nie mogê przepisaæ pliku z has³ami\n"
+
+#: src/chage.c:836
+#, c-format
+msgid "%s: no aging information present\n"
+msgstr "%s: brak informacji\n"
+
+#: src/chfn.c:107
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n"
+"\t[ -h home_ph ] [ -o other ] [ user ]\n"
+msgstr ""
+"U¿ycie: %s [ -f imiê_nazwisko ] [ -r nr_pokoju ] [ -w tel_praca ]\n"
+"\t[ -h tel_dom ] [ -o inne ] [ u¿ytkownik ]\n"
+
+#: src/chfn.c:111
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"
+msgstr ""
+"U¿ycie: %s [ -f imiê_nazwisko ] [ -r nr_pokoju ] [ -w tel_praca ] [ -h "
+"tel_dom ]\n"
+
+#: src/chfn.c:163 src/chsh.c:119
+msgid "Enter the new value, or press return for the default\n"
+msgstr "Wpisz now± warto¶æ lub wci¶nij return by przyj±c warto¶æ standardow±\n"
+
+#: src/chfn.c:166
+msgid "Full Name"
+msgstr "Imiê i nazwisko"
+
+#: src/chfn.c:168
+#, c-format
+msgid "\tFull Name: %s\n"
+msgstr "\tImiê i nazwisko: %s\n"
+
+#: src/chfn.c:171
+msgid "Room Number"
+msgstr "Numer pokoju"
+
+#: src/chfn.c:173
+#, c-format
+msgid "\tRoom Number: %s\n"
+msgstr "\tNumer pokoju: %s\n"
+
+#: src/chfn.c:176
+msgid "Work Phone"
+msgstr "Telefon do pracy"
+
+#: src/chfn.c:178
+#, c-format
+msgid "\tWork Phone: %s\n"
+msgstr "\tTelefon do pracy: %s\n"
+
+#: src/chfn.c:181
+msgid "Home Phone"
+msgstr "Telefon domowy"
+
+#: src/chfn.c:183
+#, c-format
+msgid "\tHome Phone: %s\n"
+msgstr "\tTelefon domowy: %s\n"
+
+#: src/chfn.c:186
+msgid "Other"
+msgstr "Inne"
+
+#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330
+#: src/chfn.c:391 src/passwd.c:1226
+#, c-format
+msgid "%s: Permission denied.\n"
+msgstr "%s: Brak praw dostêpu.\n"
+
+#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277
+#, c-format
+msgid "%s: Unknown user %s\n"
+msgstr "%s: Nieznany u¿ytkownik %s\n"
+
+#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207
+#, c-format
+msgid "%s: Cannot determine your user name.\n"
+msgstr "%s: Nie mogê ustaliæ twojej nazwy u¿ytkownika.\n"
+
+#: src/chfn.c:373 src/chsh.c:250
+#, c-format
+msgid "%s: cannot change user `%s' on NIS client.\n"
+msgstr "%s: nie mogê zmieniæ u¿ytkownika `%s' na kliencie NIS.\n"
+
+#: src/chfn.c:378 src/chsh.c:257
+#, c-format
+msgid "%s: `%s' is the NIS master for this client.\n"
+msgstr "%s: `%s' jest nadrzêdnym serwerm NIS dla tego klienta.\n"
+
+#: src/chfn.c:453
+#, c-format
+msgid "Changing the user information for %s\n"
+msgstr "Zmieniam informacjê o u¿ytkowniku %s\n"
+
+#: src/chfn.c:462
+#, c-format
+msgid "%s: invalid name: \"%s\"\n"
+msgstr "%s: nieprawid³owa nazwa: \"%s\"\n"
+
+#: src/chfn.c:467
+#, c-format
+msgid "%s: invalid room number: \"%s\"\n"
+msgstr "%s: nieprawid³owy numer pokoju: \"%s\"\n"
+
+#: src/chfn.c:472
+#, c-format
+msgid "%s: invalid work phone: \"%s\"\n"
+msgstr "%s: nieprawid³owy numer telefonu do pracy: \"%s\"\n"
+
+#: src/chfn.c:477
+#, c-format
+msgid "%s: invalid home phone: \"%s\"\n"
+msgstr "%s: nieprawid³owy numer telefonu domowego: \"%s\"\n"
+
+#: src/chfn.c:482
+#, c-format
+msgid "%s: \"%s\" contains illegal characters\n"
+msgstr "%s: \"%s\" zawiera nieprawid³owe znaki\n"
+
+#: src/chfn.c:494
+#, c-format
+msgid "%s: fields too long\n"
+msgstr "%s: pola zbyt d³ugie\n"
+
+#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388
+msgid "Cannot change ID to root.\n"
+msgstr "Nie mogê zmieniæ ID na root.\n"
+
+#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880
+msgid "Cannot lock the password file; try again later.\n"
+msgstr "Nie mogê zablokowaæ pliku z has³ami; spróbuj pó¼niej.\n"
+
+#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885
+msgid "Cannot open the password file.\n"
+msgstr "Nie mogê otworzyæ pliku z has³ami.\n"
+
+#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313
+#, c-format
+msgid "%s: %s not found in /etc/passwd\n"
+msgstr "%s: %s nie znaleziony w /etc/passwd\n"
+
+#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920
+#: src/passwd.c:960
+msgid "Error updating the password entry.\n"
+msgstr "B³±d podczas aktualizacji wpisu do bazy hase³.\n"
+
+#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933
+msgid "Cannot commit password file changes.\n"
+msgstr "Wprowadzenie zmian do pliku passwd jest niemo¿liwe.\n"
+
+#: src/chfn.c:592 src/chsh.c:431
+msgid "Cannot unlock the password file.\n"
+msgstr "Nie mogê usun±c blokady z pliku z has³ami.\n"
+
+#: src/chpasswd.c:76
+#, c-format
+msgid "usage: %s [-e]\n"
+msgstr "u¿ycie: %s [-e]\n"
+
+#: src/chpasswd.c:132 src/pwconv.c:104
+#, c-format
+msgid "%s: can't lock shadow file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n"
+
+#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118
+#: src/pwunconv.c:123
+#, c-format
+msgid "%s: can't open shadow file\n"
+msgstr "%s: nie mogê otworzyæ pliku z ukrytymi has³ami\n"
+
+#: src/chpasswd.c:159 src/newusers.c:415
+#, c-format
+msgid "%s: line %d: line too long\n"
+msgstr "%s: linia %d: linia zbyt d³uga\n"
+
+#: src/chpasswd.c:179
+#, c-format
+msgid "%s: line %d: missing new password\n"
+msgstr "%s: linia %d: brakuje nowego has³a\n"
+
+#: src/chpasswd.c:195
+#, c-format
+msgid "%s: line %d: unknown user %s\n"
+msgstr "%s: linia %d: nieznany u¿ytkownik %s\n"
+
+#: src/chpasswd.c:247
+#, c-format
+msgid "%s: line %d: cannot update password entry\n"
+msgstr "%s: linia %d: nie mogê zaktualizowaæ wpisu do bazy hase³\n"
+
+#: src/chpasswd.c:263 src/newusers.c:535
+#, c-format
+msgid "%s: error detected, changes ignored\n"
+msgstr "%s: wykryto b³±d, zignorowano modyfikacje\n"
+
+#: src/chpasswd.c:274
+#, c-format
+msgid "%s: error updating shadow file\n"
+msgstr "%s: b³±d podczas aktualizacji pliku z ukrytymi has³ami\n"
+
+#: src/chpasswd.c:282
+#, c-format
+msgid "%s: error updating password file\n"
+msgstr "%s: b³±d podczas aktualizacji pliku z has³ami\n"
+
+#: src/chsh.c:105
+#, c-format
+msgid "Usage: %s [ -s shell ] [ name ]\n"
+msgstr "U¿ycie: %s [ -s pow³oka ] [ nazwa ]\n"
+
+#: src/chsh.c:120
+msgid "Login Shell"
+msgstr "Pow³oka logowania"
+
+#: src/chsh.c:273 src/chsh.c:286
+#, c-format
+msgid "You may not change the shell for %s.\n"
+msgstr "Nie mo¿esz zmieniaæ pow³oki dla %s.\n"
+
+#: src/chsh.c:315
+#, c-format
+msgid "Changing the login shell for %s\n"
+msgstr "Zmieniam pow³okê logowania dla %s\n"
+
+#: src/chsh.c:327
+#, c-format
+msgid "%s: Invalid entry: %s\n"
+msgstr "%s: Nieprawid³owy wpis: %s\n"
+
+#: src/chsh.c:332
+#, c-format
+msgid "%s is an invalid shell.\n"
+msgstr "%s jest nieprawid³ow± pow³ok±.\n"
+
+#: src/dpasswd.c:69
+#, c-format
+msgid "Usage: %s [ -(a|d) ] shell\n"
+msgstr "U¿ycie: %s [ -(a|d) ] pow³oka\n"
+
+#: src/dpasswd.c:134
+msgid "Shell password: "
+msgstr "Has³o pow³oki: "
+
+#: src/dpasswd.c:140
+msgid "re-enter Shell password: "
+msgstr "Wpisz ponownie has³o pow³oki: "
+
+#: src/dpasswd.c:147
+#, c-format
+msgid "%s: Passwords do not match, try again.\n"
+msgstr "%s: Has³a nie pasuj±, spróbuj ponownie.\n"
+
+#: src/dpasswd.c:167
+#, c-format
+msgid "%s: can't create %s"
+msgstr "%s: nie mogê utworzyæ %s"
+
+#: src/dpasswd.c:172
+#, c-format
+msgid "%s: can't open %s"
+msgstr "%s: nie mogê otworzyæ %s"
+
+#: src/dpasswd.c:200
+#, c-format
+msgid "%s: Shell %s not found.\n"
+msgstr "%s: Pow³oka %s nie znaleziona.\n"
+
+#: src/expiry.c:84
+msgid "Usage: expiry { -f | -c }\n"
+msgstr "U¿ycie: expiry { -f | -c }\n"
+
+#: src/expiry.c:137
+#, c-format
+msgid "%s: WARNING! Must be set-UID root!\n"
+msgstr "%s: OSTRZE¯ENIE! Program musi posiadaæ SUID root!\n"
+
+#: src/expiry.c:148
+#, c-format
+msgid "%s: unknown user\n"
+msgstr "%s: nieznany u¿ytkownik\n"
+
+#: src/faillog.c:79
+#, c-format
+msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"
+msgstr "u¿ycie: %s [-a|-u u¿ytkownik] [-m maks] [-r] [-t dni] [-l bloksek]\n"
+
+#: src/faillog.c:134 src/lastlog.c:94
+#, c-format
+msgid "Unknown User: %s\n"
+msgstr "Nieznany u¿ytkownik: %s\n"
+
+#: src/faillog.c:215
+msgid "Username Failures Maximum Latest\n"
+msgstr "U¿ytkownik Niepowodzenia Maksymalnie Ostatnio\n"
+
+#: src/faillog.c:232
+#, c-format
+msgid " %s on %s"
+msgstr " %s na %s"
+
+#: src/faillog.c:236
+#, c-format
+msgid " [%lds left]"
+msgstr " [%lds pozosta³o]"
+
+#: src/faillog.c:239
+#, c-format
+msgid " [%lds lock]"
+msgstr " [%lds blokada]"
+
+#: src/gpasswd.c:89
+#, c-format
+msgid "usage: %s [-r|-R] group\n"
+msgstr "u¿ycie: %s [-r|-R] grupa\n"
+
+#: src/gpasswd.c:90
+#, c-format
+msgid " %s [-a user] group\n"
+msgstr " %s [-a u¿ytkownik] grupa\n"
+
+#: src/gpasswd.c:91
+#, c-format
+msgid " %s [-d user] group\n"
+msgstr " %s [-d u¿ytkownik] grupa\n"
+
+#: src/gpasswd.c:93
+#, c-format
+msgid " %s [-A user,...] [-M user,...] group\n"
+msgstr " %s [-A u¿ytkownik,...] [-M u¿ytkownik,...] grupa\n"
+
+#: src/gpasswd.c:96
+#, c-format
+msgid " %s [-M user,...] group\n"
+msgstr " %s [-M u¿ytkownik,...] grupa\n"
+
+#: src/gpasswd.c:160 src/gpasswd.c:245
+#, c-format
+msgid "%s: unknown user %s\n"
+msgstr "%s: nieznany u¿ytkownik %s\n"
+
+#: src/gpasswd.c:172
+msgid "Permission denied.\n"
+msgstr "Dostêp zabroniony.\n"
+
+#: src/gpasswd.c:257
+#, c-format
+msgid "%s: shadow group passwords required for -A\n"
+msgstr "%s: plik z ukrytymi has³ami grup wymagany dla -A\n"
+
+#: src/gpasswd.c:308
+msgid "Who are you?\n"
+msgstr "Kim jeste¶?\n"
+
+#: src/gpasswd.c:328 src/newgrp.c:251
+#, c-format
+msgid "unknown group: %s\n"
+msgstr "nieznana grupa: %s\n"
+
+#: src/gpasswd.c:436
+#, c-format
+msgid "Adding user %s to group %s\n"
+msgstr "Dodajê nowego u¿ytkownika %s do grupy %s\n"
+
+#: src/gpasswd.c:453
+#, c-format
+msgid "Removing user %s from group %s\n"
+msgstr "Usuwam u¿ytkownika %s z grupy %s\n"
+
+#: src/gpasswd.c:466
+#, c-format
+msgid "%s: unknown member %s\n"
+msgstr "%s: nieznany cz³onek %s\n"
+
+#: src/gpasswd.c:513
+#, c-format
+msgid "%s: Not a tty\n"
+msgstr "%s: To nie tty\n"
+
+#.
+#. * A new password is to be entered and it must be encrypted,
+#. * etc. The password will be prompted for twice, and both
+#. * entries must be identical. There is no need to validate
+#. * the old password since the invoker is either the group
+#. * owner, or root.
+#.
+#: src/gpasswd.c:535
+#, c-format
+msgid "Changing the password for group %s\n"
+msgstr "Zmieniam has³o dla grupy %s\n"
+
+#: src/gpasswd.c:538
+msgid "New Password: "
+msgstr "Nowe has³o: "
+
+#: src/gpasswd.c:543 src/passwd.c:422
+msgid "Re-enter new password: "
+msgstr "Wpisz has³o ponownie: "
+
+#: src/gpasswd.c:555
+msgid "They don't match; try again"
+msgstr "Nie pasuj±; spróbuj ponownie"
+
+#: src/gpasswd.c:559
+#, c-format
+msgid "%s: Try again later\n"
+msgstr "%s: Spróbuj ponownie pó¼niej\n"
+
+#: src/gpasswd.c:590
+#, c-format
+msgid "%s: can't get lock\n"
+msgstr "%s: nie mogê zablokowaæ\n"
+
+#: src/gpasswd.c:596
+#, c-format
+msgid "%s: can't get shadow lock\n"
+msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n"
+
+#: src/gpasswd.c:602
+#, c-format
+msgid "%s: can't open file\n"
+msgstr "%s: nie mogê otworzyæ pliku\n"
+
+#: src/gpasswd.c:614
+#, c-format
+msgid "%s: can't update entry\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu\n"
+
+#: src/gpasswd.c:620
+#, c-format
+msgid "%s: can't update shadow entry\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu do pliku z ukrytymi has³ami\n"
+
+#: src/gpasswd.c:626
+#, c-format
+msgid "%s: can't re-write file\n"
+msgstr "%s: nie mogê przepisaæ pliku\n"
+
+#: src/gpasswd.c:632
+#, c-format
+msgid "%s: can't re-write shadow file\n"
+msgstr "%s: nie mogê przepisaæ pliku z ukrytymi has³ami\n"
+
+#: src/gpasswd.c:640
+#, c-format
+msgid "%s: can't unlock file\n"
+msgstr "%s: nie mogê usun±c blokady z pliku\n"
+
+#: src/gpasswd.c:645
+#, c-format
+msgid "%s: can't update DBM files\n"
+msgstr "%s: nie mogê zaktualizwoaæ plików DBM\n"
+
+#: src/gpasswd.c:652
+#, c-format
+msgid "%s: can't update DBM shadow files\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku DBM z ukrytymi has³ami\n"
+
+#: src/groupadd.c:105
+msgid "usage: groupadd [-g gid [-o]] group\n"
+msgstr "u¿ycie: groupadd [-g gid [-o]] grupa\n"
+
+#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230
+#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675
+#, c-format
+msgid "%s: error adding new group entry\n"
+msgstr "%s: b³±d podczas dodawania nowej grupy\n"
+
+#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942
+#: src/usermod.c:551 src/usermod.c:687
+#, c-format
+msgid "%s: cannot add new dbm group entry\n"
+msgstr "%s: nie mogê dodaæ nowego wpisu do bazy dbm grup\n"
+
+#: src/groupadd.c:258 src/useradd.c:996
+#, c-format
+msgid "%s: name %s is not unique\n"
+msgstr "%s: nazwa %s nie jest niepowtarzalny\n"
+
+#: src/groupadd.c:273
+#, c-format
+msgid "%s: gid %ld is not unique\n"
+msgstr "%s: gid %ld nie jest niepowtarzalny\n"
+
+#: src/groupadd.c:297
+#, c-format
+msgid "%s: can't get unique gid\n"
+msgstr "%s: nie mogê uzyskaæ niepowtarzalnego gid\n"
+
+#.
+#. * All invalid group names land here.
+#.
+#: src/groupadd.c:321 src/groupmod.c:341
+#, c-format
+msgid "%s: %s is a not a valid group name\n"
+msgstr "%s: %s: nie jest prawid³ow± nazw± grupy\n"
+
+#: src/groupadd.c:350 src/groupmod.c:367
+#, c-format
+msgid "%s: invalid group %s\n"
+msgstr "%s: nieprawid³owa grupa %s\n"
+
+#: src/groupadd.c:367 src/useradd.c:1272
+#, c-format
+msgid "%s: -O requires NAME=VALUE\n"
+msgstr "%s: -O wymaga ZMIENNA=WARTO¦Æ\n"
+
+#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381
+#: src/userdel.c:303 src/usermod.c:563
+#, c-format
+msgid "%s: cannot rewrite group file\n"
+msgstr "%s: nie mogê przepisaæ pliku z grupami\n"
+
+#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389
+#: src/userdel.c:309 src/usermod.c:700
+#, c-format
+msgid "%s: cannot rewrite shadow group file\n"
+msgstr "%s: nie mogê przepisaæ pliku z ukrytymi grupami\n"
+
+#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389
+#, c-format
+msgid "%s: unable to lock group file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z grupami\n"
+
+#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432
+#, c-format
+msgid "%s: unable to open group file\n"
+msgstr "%s: nie mogê otworzyæ pliku z grupami\n"
+
+#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398
+#, c-format
+msgid "%s: unable to lock shadow group file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi grupami\n"
+
+#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442
+#, c-format
+msgid "%s: unable to open shadow group file\n"
+msgstr "%s: nie mogê otworzyæ pliku z ukrytymi grupami\n"
+
+#: src/groupadd.c:518
+#, c-format
+msgid "%s: group %s exists\n"
+msgstr "%s: grupa %s istnieje\n"
+
+#: src/groupdel.c:86
+msgid "usage: groupdel group\n"
+msgstr "u¿ycie: groupdel grupa\n"
+
+#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234
+#, c-format
+msgid "%s: error removing group entry\n"
+msgstr "%s: b³±d podczas usuwania grupy\n"
+
+#: src/groupdel.c:116 src/groupmod.c:206
+#, c-format
+msgid "%s: error removing group dbm entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu dbm o grupie\n"
+
+#: src/groupdel.c:131
+#, c-format
+msgid "%s: error removing shadow group entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu o ukrytej grupie\n"
+
+#: src/groupdel.c:144 src/groupmod.c:252
+#, c-format
+msgid "%s: error removing shadow group dbm entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu dbm z pliku ukrytych grup\n"
+
+#.
+#. * Can't remove the group.
+#.
+#: src/groupdel.c:248
+#, c-format
+msgid "%s: cannot remove user's primary group.\n"
+msgstr "%s: nie mogê usun±æ podstawowej grupy u¿ytkowników.\n"
+
+#: src/groupdel.c:305 src/groupmod.c:501
+#, c-format
+msgid "%s: group %s does not exist\n"
+msgstr "%s: grupa %s nie isnieje\n"
+
+#: src/groupdel.c:319 src/groupmod.c:517
+#, c-format
+msgid "%s: group %s is a NIS group\n"
+msgstr "%s: grupa %s jest grup± NIS\n"
+
+#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016
+#, c-format
+msgid "%s: %s is the NIS master\n"
+msgstr "%s: %s jest g³ównym serwerem NIS\n"
+
+#: src/groupmod.c:105
+msgid "usage: groupmod [-g gid [-o]] [-n name] group\n"
+msgstr "u¿ycie: groupmod [-g gid [-o]] [-n nazwa] grupa\n"
+
+#: src/groupmod.c:165
+#, fuzzy, c-format
+msgid "%s: %s not found in /etc/group\n"
+msgstr "%s: %s nie znaleziony w /etc/passwd\n"
+
+#: src/groupmod.c:246
+#, c-format
+msgid "%s: cannot add new dbm shadow group entry\n"
+msgstr "%s: nie mogê dodaæ nowego wpisu dbm do pliku z ukrytymi grupami\n"
+
+#: src/groupmod.c:299
+#, c-format
+msgid "%s: %ld is not a unique gid\n"
+msgstr "%s: %ld nie jest niepowtarzalnym gid\n"
+
+#: src/groupmod.c:330
+#, c-format
+msgid "%s: %s is not a unique name\n"
+msgstr "%s: %s nie jest niepowtarzaln± nazw±\n"
+
+#: src/groups.c:62
+#, c-format
+msgid "unknown user %s\n"
+msgstr "nieznany u¿ytkownik %s\n"
+
+#: src/grpck.c:98
+#, c-format
+msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n"
+msgstr "U¿ycie: %s [ -r ] [ grupa [ gshadow ] ]\n"
+
+#: src/grpck.c:100
+#, c-format
+msgid "Usage: %s [ -r ] [ group ]\n"
+msgstr "U¿ycie: %s [ -r ] [ grupa ]\n"
+
+#: src/grpck.c:119 src/pwck.c:119
+msgid "No"
+msgstr "Nie"
+
+#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225
+#, c-format
+msgid "%s: cannot lock file %s\n"
+msgstr "%s: nie mogê zablokowaæ pliku %s\n"
+
+#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241
+#: src/pwck.c:250
+#, c-format
+msgid "%s: cannot open file %s\n"
+msgstr "%s: nie mogê otworzyæ pliku %s\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:298
+msgid "invalid group file entry\n"
+msgstr "nieprawid³owy wpis do pliku grup\n"
+
+#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517
+#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517
+#: src/pwck.c:541
+#, c-format
+msgid "delete line `%s'? "
+msgstr "usun±c liniê `%s'? "
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:361
+msgid "duplicate group entry\n"
+msgstr "duplikat wpisu grup\n"
+
+#: src/grpck.c:378
+#, c-format
+msgid "invalid group name `%s'\n"
+msgstr "nieprawid³owa nazwa grupy `%s'\n"
+
+#: src/grpck.c:388
+#, c-format
+msgid "group %s: bad GID (%d)\n"
+msgstr "grupa %s: z³y GID (%d)\n"
+
+#: src/grpck.c:414
+#, c-format
+msgid "group %s: no user %s\n"
+msgstr "grupa %s: nie ma u¿ytkownika %s\n"
+
+#: src/grpck.c:416 src/grpck.c:585
+#, c-format
+msgid "delete member `%s'? "
+msgstr "skasowaæ cz³onka `%s'? "
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:453
+msgid "invalid shadow group file entry\n"
+msgstr "nieprawid³owy wpis do pliku z ukrytymi has³ami\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:516
+msgid "duplicate shadow group entry\n"
+msgstr "duplikuj±cy siê wpis w pliku ukrytych grup\n"
+
+#: src/grpck.c:533
+msgid "no matching group file entry\n"
+msgstr "brak pasuj±cego wpisu w pliku grup\n"
+
+#: src/grpck.c:553
+#, c-format
+msgid "shadow group %s: no administrative user %s\n"
+msgstr "ukryta grupa %s: brak u¿ytkownika administracyjnego %s\n"
+
+#: src/grpck.c:555
+#, c-format
+msgid "delete administrative member `%s'? "
+msgstr "usun±æ cz³onka administracyjnego `%s'? "
+
+#: src/grpck.c:583
+#, c-format
+msgid "shadow group %s: no user %s\n"
+msgstr "ukryta grupa %s: nie ma u¿ytkownika %s\n"
+
+#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580
+#, c-format
+msgid "%s: cannot update file %s\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku %s\n"
+
+#: src/grpck.c:640 src/pwck.c:606
+#, c-format
+msgid "%s: the files have been updated; run mkpasswd\n"
+msgstr "%s: pliki zosta³y zaktualizowane; uruchom mkpasswd\n"
+
+#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611
+#, c-format
+msgid "%s: no changes\n"
+msgstr "%s: bez zmian\n"
+
+#: src/grpck.c:644 src/pwck.c:610
+#, c-format
+msgid "%s: the files have been updated\n"
+msgstr "%s: pliku zost³y zaktualizowane\n"
+
+#: src/grpconv.c:62 src/grpunconv.c:63
+#, c-format
+msgid "%s: can't lock group file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z grupami\n"
+
+#: src/grpconv.c:67 src/grpunconv.c:68
+#, c-format
+msgid "%s: can't open group file\n"
+msgstr "%s: nie mogê otworzyæ pliku z grupami\n"
+
+#: src/grpconv.c:72 src/grpunconv.c:73
+#, c-format
+msgid "%s: can't lock shadow group file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z przes³oniêtymi grupami\n"
+
+#: src/grpconv.c:77 src/grpunconv.c:78
+#, c-format
+msgid "%s: can't open shadow group file\n"
+msgstr "%s: nie mogê otworzyæ pliku z przes³oniêtymi grupami\n"
+
+#.
+#. * This shouldn't happen (the entry exists) but...
+#.
+#: src/grpconv.c:93
+#, c-format
+msgid "%s: can't remove shadow group %s\n"
+msgstr "%s: nie mogê usun±æ ukrytej grupy %s\n"
+
+#: src/grpconv.c:134 src/pwconv.c:160
+#, c-format
+msgid "%s: can't update shadow entry for %s\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu ukrytej grupy dla %s\n"
+
+#: src/grpconv.c:143 src/grpunconv.c:94
+#, c-format
+msgid "%s: can't update entry for group %s\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu dla grupy %s\n"
+
+#: src/grpconv.c:150 src/grpunconv.c:102
+#, c-format
+msgid "%s: can't update shadow group file\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku z ukrytymi grupami\n"
+
+#: src/grpconv.c:154 src/grpunconv.c:107
+#, c-format
+msgid "%s: can't update group file\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku z grupami\n"
+
+#: src/grpconv.c:169 src/grpunconv.c:128
+#, c-format
+msgid "%s: not configured for shadow group support.\n"
+msgstr "%s: nie skonfigurowany dla wsparcia ukrytych grup.\n"
+
+#: src/grpunconv.c:112
+#, c-format
+msgid "%s: can't delete shadow group file\n"
+msgstr "%s: nie mogê skasowaæ pliku z ukrytymi grupami\n"
+
+#: src/id.c:56
+msgid "usage: id [ -a ]\n"
+msgstr "u¿ycie: id [ -a ]\n"
+
+#: src/id.c:58
+msgid "usage: id\n"
+msgstr "u¿ycie: id\n"
+
+#: src/id.c:118
+#, c-format
+msgid "uid=%d(%s)"
+msgstr "uid=%d(%s)"
+
+#: src/id.c:120
+#, c-format
+msgid "uid=%d"
+msgstr "uid=%d"
+
+#: src/id.c:124
+#, c-format
+msgid " gid=%d(%s)"
+msgstr " gid=%d(%s)"
+
+#: src/id.c:126
+#, c-format
+msgid " gid=%d"
+msgstr " gid=%d"
+
+#: src/id.c:136
+#, c-format
+msgid " euid=%d(%s)"
+msgstr " euid=%d(%s)"
+
+#: src/id.c:138
+#, c-format
+msgid " euid=%d"
+msgstr " euid=%d"
+
+#: src/id.c:143
+#, c-format
+msgid " egid=%d(%s)"
+msgstr " egid=%d(%s)"
+
+#: src/id.c:145
+#, c-format
+msgid " egid=%d"
+msgstr " egid=%d"
+
+#.
+#. * Start off the group message. It will be of the format
+#. *
+#. * groups=###(aaa),###(aaa),###(aaa)
+#. *
+#. * where "###" is a numerical value and "aaa" is the
+#. * corresponding name for each respective numerical value.
+#.
+#: src/id.c:166
+msgid " groups="
+msgstr " grupy="
+
+#: src/lastlog.c:167
+msgid "Username Port From Latest\n"
+msgstr "U¿ytkownik Port Z Ostatnio\n"
+
+#: src/lastlog.c:169
+msgid "Username Port Latest\n"
+msgstr "U¿ytkownik Port Ostatnio\n"
+
+#: src/lastlog.c:183
+msgid "**Never logged in**"
+msgstr "**Nigdy nie zalogowany**"
+
+#: src/login.c:198
+#, c-format
+msgid "usage: %s [-p] [name]\n"
+msgstr "u¿ycie: %s [-p] [nazwa]\n"
+
+#: src/login.c:201
+#, c-format
+msgid " %s [-p] [-h host] [-f name]\n"
+msgstr " %s [-p] [-h host] [-f nazwa]\n"
+
+#: src/login.c:203
+#, c-format
+msgid " %s [-p] -r host\n"
+msgstr " %s [-p] -r host\n"
+
+#: src/login.c:286
+msgid "Invalid login time\n"
+msgstr "Nieprawid³owy czas logowania\n"
+
+#: src/login.c:341
+msgid ""
+"\n"
+"System closed for routine maintenance\n"
+msgstr ""
+"\n"
+"System zamkniêty do rutynowej konserwacji.\n"
+
+#: src/login.c:351
+msgid ""
+"\n"
+"[Disconnect bypassed -- root login allowed.]\n"
+msgstr ""
+"\n"
+"[Roz³±czenie pominiête -- zezwolenie na logowanie siê root-a.]\n"
+
+#: src/login.c:390
+#, c-format
+msgid ""
+"\n"
+"Login timed out after %d seconds.\n"
+msgstr ""
+"\n"
+"Limit czasu logowania przekroczony po %d sekundach.\n"
+
+#: src/login.c:692
+#, c-format
+msgid " on `%.100s' from `%.200s'"
+msgstr " na `%s.100s' z `%.200s'"
+
+#: src/login.c:694
+#, c-format
+msgid " on `%.100s'"
+msgstr " na `%.100s'"
+
+#: src/login.c:834
+#, c-format
+msgid ""
+"\n"
+"%s login: "
+msgstr ""
+"\n"
+"%s login: "
+
+#: src/login.c:836
+msgid "login: "
+msgstr "login: "
+
+#: src/login.c:1026 src/sulogin.c:231
+msgid "Login incorrect"
+msgstr "Nieprawid³owe logowanie"
+
+#: src/login.c:1213
+msgid "Warning: login re-enabled after temporary lockout.\n"
+msgstr "Ostrze¿enie: logowanie ponownie odblokowanie po czasowej blokadzie.\n"
+
+#: src/login.c:1223
+#, c-format
+msgid "Last login: %s on %s"
+msgstr "Ostatnie logowanie: %s na %s"
+
+#: src/login.c:1226
+#, c-format
+msgid "Last login: %.19s on %s"
+msgstr "Ostatnie logowanie: %s na %s"
+
+#: src/login.c:1231
+#, c-format
+msgid " from %.*s"
+msgstr " z %.*s"
+
+#: src/login.c:1303
+msgid "Starting rad_login\n"
+msgstr "Startujê rad_login\n"
+
+#: src/mkpasswd.c:49
+#, c-format
+msgid "%s: no DBM database on system - no action performed\n"
+msgstr ""
+"%s: nie ma bazy DBM na tym systemie - ¿adna akcja nie zosta³a podjêta\n"
+
+#: src/mkpasswd.c:245 src/mkpasswd.c:249
+#, c-format
+msgid "%s: cannot overwrite file %s\n"
+msgstr "%s: nie mogê nadpisaæ pliku %s\n"
+
+#: src/mkpasswd.c:263
+#, c-format
+msgid "%s: cannot open DBM files for %s\n"
+msgstr "%s: nie mogê otworzyæ plików DBM dla %s\n"
+
+#: src/mkpasswd.c:296
+#, c-format
+msgid "%s: the beginning with "
+msgstr "%s: rozpoczyna siê od "
+
+#: src/mkpasswd.c:321
+#, c-format
+msgid "%s: error parsing line \"%s\"\n"
+msgstr "%s: b³±d podczas przetwarzania lini \"%s\"\n"
+
+#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332
+msgid "adding record for name "
+msgstr "dodajê rekord do nazwy "
+
+#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349
+#, c-format
+msgid "%s: error adding record for "
+msgstr "%s: b³±d podczas dodawania rekordu dla "
+
+#: src/mkpasswd.c:367
+#, c-format
+msgid "added %d entries, longest was %d\n"
+msgstr "dodano %d wpisów, najd³u¿szy by³ %d\n"
+
+#: src/mkpasswd.c:382
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"
+msgstr "U¿ycie: %s [ -vf ] [ -p|g|sp|sg ] plik\n"
+
+#: src/mkpasswd.c:384
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n"
+msgstr "U¿ycie: %s [ -vf ] [ -p|g|sp ] plik\n"
+
+#: src/mkpasswd.c:387
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g ] file\n"
+msgstr "U¿ycie: %s [ -vf ] [ -p|g ] plik\n"
+
+#: src/newgrp.c:66
+msgid "usage: newgrp [ - ] [ group ]\n"
+msgstr "u¿ycie: newgrp [ - ] [ grupa ]\n"
+
+#: src/newgrp.c:68
+#, fuzzy
+msgid "usage: sg group [[-c] command ]\n"
+msgstr "u¿ycie: sg grupa [ komenda ]\n"
+
+#: src/newgrp.c:125
+#, c-format
+msgid "unknown uid: %d\n"
+msgstr "nieznany uid: %d\n"
+
+#: src/newgrp.c:201
+#, c-format
+msgid "unknown gid: %ld\n"
+msgstr "nieznany gid: %ld\n"
+
+#: src/newgrp.c:245
+#, c-format
+msgid "unknown gid: %d\n"
+msgstr "nieznany gid: %d\n"
+
+#: src/newgrp.c:323 src/newgrp.c:332
+msgid "Sorry.\n"
+msgstr "Wybacz.\n"
+
+#: src/newgrp.c:364
+msgid "too many groups\n"
+msgstr "zbyt wiele grup\n"
+
+#: src/newusers.c:76
+#, c-format
+msgid "Usage: %s [ input ]\n"
+msgstr "U¿ycie: %s [ wej¶cie ]\n"
+
+#: src/newusers.c:364
+#, c-format
+msgid "%s: can't lock /etc/passwd.\n"
+msgstr "%s: nie mogê zablokowaæ /etc/passwd.\n"
+
+#: src/newusers.c:375
+#, c-format
+msgid "%s: can't lock files, try again later\n"
+msgstr "%s: nie mogê zablokowaæ plików, spróbuj pó¼niej\n"
+
+#: src/newusers.c:390
+#, c-format
+msgid "%s: can't open files\n"
+msgstr "%s: nie mogê otworzyæ plików\n"
+
+#: src/newusers.c:435
+#, c-format
+msgid "%s: line %d: invalid line\n"
+msgstr "%s: linia %d: nieprawid³owa linia\n"
+
+#: src/newusers.c:453
+#, c-format
+msgid "%s: line %d: can't create GID\n"
+msgstr "%s: linia %d: nie mogê utworzyæ GID\n"
+
+#: src/newusers.c:469
+#, c-format
+msgid "%s: line %d: can't create UID\n"
+msgstr "%s: linia %d: nie mogê utworzyæ UID\n"
+
+#: src/newusers.c:481
+#, c-format
+msgid "%s: line %d: cannot find user %s\n"
+msgstr "%s: linia %d: nie mogê znale¶æ u¿ytkownika %s\n"
+
+#: src/newusers.c:489
+#, c-format
+msgid "%s: line %d: can't update password\n"
+msgstr "%s: linia %d: nie mogê zaktualizowaæ pliku z has³ami\n"
+
+#: src/newusers.c:506
+#, c-format
+msgid "%s: line %d: mkdir failed\n"
+msgstr "%s: linia %d: mkdir nie powiod³o siê\n"
+
+#: src/newusers.c:510
+#, c-format
+msgid "%s: line %d: chown failed\n"
+msgstr "%s: linia %d: chown nie powiod³o siê\n"
+
+#: src/newusers.c:519
+#, c-format
+msgid "%s: line %d: can't update entry\n"
+msgstr "%s: linia %d: nie mogê zaktualizowaæ wpisu\n"
+
+#: src/newusers.c:550
+#, c-format
+msgid "%s: error updating files\n"
+msgstr "%s: b³±d podczas aktualizowania plików\n"
+
+#: src/passwd.c:239
+#, c-format
+msgid "usage: %s [ -f | -s ] [ name ]\n"
+msgstr "u¿ycie: %s [ -f | -s ] [ nazwa ]\n"
+
+#: src/passwd.c:242
+#, c-format
+msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"
+msgstr " %s [ -x maks ] [ -n min ] [ -w ostrz ] [ -i nieakty ] nazwa\n"
+
+#: src/passwd.c:245
+#, c-format
+msgid " %s { -l | -u | -d | -S | -e } name\n"
+msgstr " %s { -l | -u | -d | -S | -e } nazwa\n"
+
+#: src/passwd.c:347
+#, c-format
+msgid "User %s has a TCFS key, his old password is required.\n"
+msgstr "U¿ytkownik %s posiada klucz TCFS, jego stare has³o jest wymagane.\n"
+
+#: src/passwd.c:348
+msgid "You can use -t option to force the change.\n"
+msgstr "Nie mo¿esz u¿ywaæ opcji -t by wymusiæ zmianê.\n"
+
+#: src/passwd.c:354
+msgid "Old password: "
+msgstr "Stare has³o: "
+
+#: src/passwd.c:361
+#, c-format
+msgid "Incorrect password for `%s'\n"
+msgstr "Nieprawid³owe has³o `%s'\n"
+
+#: src/passwd.c:374
+#, c-format
+msgid "Warning: user %s has a TCFS key.\n"
+msgstr "Ostrze¿enie: u¿ytkownik %s posiada klucz TCFS.\n"
+
+#: src/passwd.c:392
+#, c-format
+msgid ""
+"Enter the new password (minimum of %d, maximum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"
+msgstr ""
+"Wpisz nowe has³o (minimum %d, maksimum %d znaków)\n"
+"Proszê u¿yj kombinacji wielkich i ma³ych znaków oraz cyfr.\n"
+
+#: src/passwd.c:399
+msgid "New password: "
+msgstr "Nowe has³o: "
+
+#: src/passwd.c:409
+msgid "Try again.\n"
+msgstr "Spróbuj ponownie.\n"
+
+#: src/passwd.c:418
+msgid ""
+"\n"
+"Warning: weak password (enter it again to use it anyway).\n"
+msgstr ""
+"\n"
+"Ostrze¿enie: s³abe has³o (jednak wpisz je ponowie je¶li chcesz go u¿yæ).\n"
+
+#: src/passwd.c:427
+msgid "They don't match; try again.\n"
+msgstr "Nie pasuj±; spróbuj ponownie.\n"
+
+#: src/passwd.c:512 src/passwd.c:528
+#, c-format
+msgid "The password for %s cannot be changed.\n"
+msgstr "Has³o dla %s nie mo¿e byæ zmienione.\n"
+
+#: src/passwd.c:556
+#, c-format
+msgid "Sorry, the password for %s cannot be changed yet.\n"
+msgstr "Wybacz, has³o dla %s nie mo¿e byæ jeszcze zmienione.\n"
+
+#: src/passwd.c:693
+#, c-format
+msgid "%s: out of memory\n"
+msgstr "%s: brak pamiêci\n"
+
+#: src/passwd.c:845
+msgid "Cannot lock the TCFS key database; try again later\n"
+msgstr "Nie mogê zablokowaæ bazy kluczy TCFS; spróbuj ponownie\n"
+
+#: src/passwd.c:851
+msgid "Cannot open the TCFS key database.\n"
+msgstr "Nie mogê otworzyæ bazy kluczy TCFS.\n"
+
+#: src/passwd.c:857
+msgid "Error updating the TCFS key database.\n"
+msgstr "B³±d podczas aktualizacji bazy kluczy TCFS.\n"
+
+#: src/passwd.c:862
+msgid "Cannot commit TCFS changes.\n"
+msgstr "Nie mogê potwierdziæ zmian TCFS.\n"
+
+#: src/passwd.c:1069
+#, c-format
+msgid "%s: Cannot execute %s"
+msgstr "%s: Nie mogê wykonaæ %s"
+
+#: src/passwd.c:1176
+#, c-format
+msgid "%s: repository %s not supported\n"
+msgstr "%s: ropozytorium %s nie jest obs³ugiwane\n"
+
+#: src/passwd.c:1263
+#, c-format
+msgid "%s: Permission denied\n"
+msgstr "%s: Dostêp zabroniony\n"
+
+#: src/passwd.c:1287
+#, c-format
+msgid "You may not change the password for %s.\n"
+msgstr "Nie mo¿esz zmieniaæ has³a dla %s.\n"
+
+#: src/passwd.c:1352
+#, c-format
+msgid "Changing password for %s\n"
+msgstr "Zmieniam has³o dla %s\n"
+
+#: src/passwd.c:1356
+#, c-format
+msgid "The password for %s is unchanged.\n"
+msgstr "Has³o dla %s pozostaje niezmienione.\n"
+
+#: src/passwd.c:1412
+msgid "Password changed.\n"
+msgstr "Has³o zmienione.\n"
+
+#: src/pwck.c:98
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"
+msgstr "U¿ycie: %s [ -qr ] [ has³o [ shadow ] ]\n"
+
+#: src/pwck.c:100
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd ]\n"
+msgstr "U¿ycie: %s [ -qr ] [ has³o ]\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:285
+msgid "invalid password file entry\n"
+msgstr "nieprawid³owy wpis do pliku z has³ami\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:347
+msgid "duplicate password entry\n"
+msgstr "duplikuj±cy siê wpis w pliku z has³ami\n"
+
+#: src/pwck.c:363
+#, c-format
+msgid "invalid user name `%s'\n"
+msgstr "nieprawid³owa nazwa u¿ytkownika `%s'\n"
+
+#: src/pwck.c:373
+#, c-format
+msgid "user %s: bad UID (%d)\n"
+msgstr "u¿ytkownik %s: z³y UID (%d)\n"
+
+#.
+#. * No primary group, just give a warning
+#.
+#: src/pwck.c:388
+#, c-format
+msgid "user %s: no group %d\n"
+msgstr "u¿ytkownik %s: brak grupy %d\n"
+
+#.
+#. * Home directory doesn't exist, give a warning
+#.
+#: src/pwck.c:403
+#, c-format
+msgid "user %s: directory %s does not exist\n"
+msgstr "u¿ytkownik %s: katalog %s nie istnieje\n"
+
+#.
+#. * Login shell doesn't exist, give a warning
+#.
+#: src/pwck.c:418
+#, c-format
+msgid "user %s: program %s does not exist\n"
+msgstr "u¿ytkownik %s: program %s nie istnieje\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:454
+msgid "invalid shadow password file entry\n"
+msgstr "nieprawid³owy wpis w pliku z has³ami\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:516
+msgid "duplicate shadow password entry\n"
+msgstr "duplikuj±cy siê wpis w pliku z ukrytymi has³ami\n"
+
+#.
+#. * Tell the user this entry has no matching
+#. * /etc/passwd entry and ask them to delete it.
+#.
+#: src/pwck.c:540
+msgid "no matching password file entry\n"
+msgstr "brak pasuj±cego wpisu w pliku z has³ami\n"
+
+#: src/pwck.c:557
+#, c-format
+msgid "user %s: last password change in the future\n"
+msgstr "u¿ytkownik %s: ostatnia zmiana has³a w przysz³o¶ci\n"
+
+#: src/pwconv.c:94 src/pwunconv.c:108
+#, c-format
+msgid "%s: can't lock passwd file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z has³ami\n"
+
+#: src/pwconv.c:99 src/pwunconv.c:113
+#, c-format
+msgid "%s: can't open passwd file\n"
+msgstr "%s: nie mogê otworzyæ pliku z has³ami\n"
+
+#: src/pwconv.c:126
+#, c-format
+msgid "%s: can't remove shadow entry for %s\n"
+msgstr "%s: nie mogê usun±æ wpisu z pliku z ukrytymi has³ami dla %s\n"
+
+#: src/pwconv.c:169
+#, c-format
+msgid "%s: can't update passwd entry for %s\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu do pliku z has³ami dla %s\n"
+
+#: src/pwconv.c:176
+#, c-format
+msgid "%s: can't update shadow file\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku z ukrytymi has³ami\n"
+
+#: src/pwconv.c:180
+#, c-format
+msgid "%s: can't update passwd file\n"
+msgstr "%s: nie mogê zaktualizowaæ pliku z has³ami\n"
+
+#: src/pwunconv.c:62
+#, c-format
+msgid "%s: Shadow passwords are not configured.\n"
+msgstr "%s: Przes³oniête has³a nie s± skonfigurowane.\n"
+
+#: src/pwunconv.c:171
+#, c-format
+msgid "%s: can't update entry for user %s\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu dla u¿ytkownika %s\n"
+
+#: src/pwunconv.c:188
+#, c-format
+msgid "%s: can't delete shadow password file\n"
+msgstr "%s: nie mogê skasowaæ pliku z ukrytymi has³ami\n"
+
+#: src/su.c:140
+msgid "Sorry."
+msgstr "Wybacz."
+
+#: src/su.c:222
+#, c-format
+msgid "%s: must be run from a terminal\n"
+msgstr "%s: musisz uruchamiaæ z terminala\n"
+
+#: src/su.c:311
+#, c-format
+msgid "%s: pam_start: error %d\n"
+msgstr "%s: pam_start: b³±d %d\n"
+
+#: src/su.c:337
+#, c-format
+msgid "Unknown id: %s\n"
+msgstr "Nieznany id: %s\n"
+
+#. access denied (-1) or unexpected value
+#: src/su.c:372 src/su.c:387
+#, c-format
+msgid "You are not authorized to su %s\n"
+msgstr "Nie masz autoryzacji by u¿ywaæ su %s\n"
+
+#. require own password
+#: src/su.c:383
+msgid "(Enter your own password.)"
+msgstr "(Wpisz swoje w³asne has³o.)"
+
+#: src/su.c:404
+#, c-format
+msgid "%s: permission denied (shell).\n"
+msgstr "%s: dostêp zabroniony (pow³oka).\n"
+
+#: src/su.c:428
+#, c-format
+msgid ""
+"%s: %s\n"
+"(Ignored)\n"
+msgstr ""
+"%s: %s\n"
+"(Zignorowano)\n"
+
+#: src/su.c:628
+msgid "No shell\n"
+msgstr "Brak pow³oki\n"
+
+#. must be a password file!
+#: src/sulogin.c:136
+msgid "No password file\n"
+msgstr "Brak pliku z has³ami\n"
+
+#.
+#. * Fail secure
+#.
+#: src/sulogin.c:178
+msgid "No password entry for 'root'\n"
+msgstr "Brak wpisu do bazy hase³ dla 'root'\n"
+
+#.
+#. * Here we prompt for the root password, or if no password is
+#. * given we just exit.
+#.
+#. get a password for root
+#: src/sulogin.c:192
+msgid ""
+"\n"
+"Type control-d to proceed with normal startup,\n"
+"(or give root password for system maintenance):"
+msgstr ""
+"\n"
+"Wpisz control-d by kontynuowaæ normalny start,\n"
+"(lub podaj has³o root-a by przej¶æ do trybu utrzymania systemu):"
+
+#. make new environment active
+#: src/sulogin.c:241
+msgid "Entering System Maintenance Mode\n"
+msgstr "Wchodzê w tryb utrzymania systemu\n"
+
+#: src/useradd.c:243
+#, c-format
+msgid "%s: rebuild the group database\n"
+msgstr "%s: przebuduj bazê grup\n"
+
+#: src/useradd.c:250
+#, c-format
+msgid "%s: rebuild the shadow group database\n"
+msgstr "%s: przebuduj bazê przes³oniêtych hase³\n"
+
+#: src/useradd.c:287 src/usermod.c:967
+#, c-format
+msgid "%s: invalid numeric argument `%s'\n"
+msgstr "%s: nieprawid³owy argument numeryczny `%s'\n"
+
+#: src/useradd.c:343
+#, c-format
+msgid "%s: unknown gid %s\n"
+msgstr "%s: nieznany gid %s\n"
+
+#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254
+#: src/usermod.c:1098
+#, c-format
+msgid "%s: unknown group %s\n"
+msgstr "%s: nieznana grupa %s\n"
+
+#: src/useradd.c:418
+#, c-format
+msgid "group=%s,%ld basedir=%s skel=%s\n"
+msgstr "grupa=%s,%ld kat_baz=%s skel=%s\n"
+
+#: src/useradd.c:421
+#, c-format
+msgid "shell=%s "
+msgstr "pow³oka=%s "
+
+#: src/useradd.c:423
+#, c-format
+msgid "inactive=%ld expire=%s"
+msgstr "nieaktywne=%ld wyga¶niêcie=%s"
+
+#: src/useradd.c:427
+#, c-format
+msgid "GROUP=%ld\n"
+msgstr "GRUPA=%ld\n"
+
+#: src/useradd.c:428
+#, c-format
+msgid "HOME=%s\n"
+msgstr "KAT_DOM=%s\n"
+
+#: src/useradd.c:430
+#, c-format
+msgid "INACTIVE=%ld\n"
+msgstr "NIEAKTYWNE=%ld\n"
+
+#: src/useradd.c:431
+#, c-format
+msgid "EXPIRE=%s\n"
+msgstr "WYGA¦NIÊCIE=%s\n"
+
+#: src/useradd.c:433
+#, c-format
+msgid "SHELL=%s\n"
+msgstr "POW£OKA=%s\n"
+
+#: src/useradd.c:434
+#, c-format
+msgid "SKEL=%s\n"
+msgstr "SKEL=%s\n"
+
+#: src/useradd.c:470
+#, c-format
+msgid "%s: cannot create new defaults file\n"
+msgstr "%s: nie mogê utworzyæ nowego pliku ze standardowymi ustawieniami\n"
+
+#: src/useradd.c:564 src/useradd.c:575
+#, c-format
+msgid "%s: rename: %s"
+msgstr "%s: zmiana nazwy: %s"
+
+#: src/useradd.c:662 src/usermod.c:274
+#, c-format
+msgid "%s: group `%s' is a NIS group.\n"
+msgstr "%s: grupa `%s' jest grup± NIS.\n"
+
+#: src/useradd.c:670 src/usermod.c:282
+#, c-format
+msgid "%s: too many groups specified (max %d).\n"
+msgstr "%s: podano zbyt wiele grup (maks %d).\n"
+
+#: src/useradd.c:702 src/usermod.c:314
+#, c-format
+msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"
+msgstr "u¿ycie: %s\t[-u uid [-o]] [-g grupa] [-G grupa,...] \n"
+
+#: src/useradd.c:705
+msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n"
+msgstr "\t\t[-d kat_dom] [-s pow³oka] [-c komentarz] [-m [-k wzór]]\n"
+
+#: src/useradd.c:708 src/usermod.c:320
+msgid "[-f inactive] [-e expire ] "
+msgstr "[-f nieaktywne] [-e utrata_wa¿no¶ci ]"
+
+#: src/useradd.c:711
+msgid "[-A program] "
+msgstr "[-A program] "
+
+#: src/useradd.c:713
+msgid "[-p passwd] name\n"
+msgstr "[-p has³o] nazwa\n"
+
+#: src/useradd.c:715
+#, c-format
+msgid " %s\t-D [-g group] [-b base] [-s shell]\n"
+msgstr " %s\t-D [-g grupa] [-b baza] [-s pow³oka]\n"
+
+#: src/useradd.c:718
+msgid "\t\t[-f inactive] [-e expire ]\n"
+msgstr "\t\t[-f nieaktywne] [-e utrata_wa¿no¶ci ]\n"
+
+#: src/useradd.c:815 src/usermod.c:472
+#, c-format
+msgid "%s: error locking group file\n"
+msgstr "%s: b³±d podczas blokowania pliku z grupami\n"
+
+#: src/useradd.c:819 src/usermod.c:477
+#, c-format
+msgid "%s: error opening group file\n"
+msgstr "%s: b³±d podczas otwierania pliku z grupami\n"
+
+#: src/useradd.c:824 src/usermod.c:584
+#, c-format
+msgid "%s: error locking shadow group file\n"
+msgstr "%s: b³±d podczas blokowania pliku z ukrytymi has³ami\n"
+
+#: src/useradd.c:829 src/usermod.c:590
+#, c-format
+msgid "%s: error opening shadow group file\n"
+msgstr "%s: b³±d podczas otwierania pliku z ukrytymi grupami\n"
+
+#: src/useradd.c:1001
+#, c-format
+msgid "%s: uid %d is not unique\n"
+msgstr "%s: uid %d nie jest niepowtarzalny\n"
+
+#: src/useradd.c:1031
+#, c-format
+msgid "%s: can't get unique uid\n"
+msgstr "%s: nie mogê uzyskaæ niepowtarzalnego uid\n"
+
+#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057
+#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157
+#, c-format
+msgid "%s: invalid field `%s'\n"
+msgstr "%s: nieprawid³owe pole `%s'\n"
+
+#: src/useradd.c:1153
+#, c-format
+msgid "%s: invalid base directory `%s'\n"
+msgstr "%s: nieprawid³owy katalog bazowy `%s'\n"
+
+#: src/useradd.c:1163
+#, c-format
+msgid "%s: invalid comment `%s'\n"
+msgstr "%s: nieprawid³owy komentarz `%s'\n"
+
+#: src/useradd.c:1173
+#, c-format
+msgid "%s: invalid home directory `%s'\n"
+msgstr "%s: nieprawid³owy katalog domowy `%s'\n"
+
+#: src/useradd.c:1191 src/usermod.c:1080
+#, c-format
+msgid "%s: invalid date `%s'\n"
+msgstr "%s: nieprawid³owa data `%s'\n"
+
+#: src/useradd.c:1203
+#, c-format
+msgid "%s: shadow passwords required for -e\n"
+msgstr "%s: ukryte has³a wymagane dla -e\n"
+
+#: src/useradd.c:1218
+#, c-format
+msgid "%s: shadow passwords required for -f\n"
+msgstr "%s: ukryte has³a wymagane dla -f\n"
+
+#: src/useradd.c:1292
+#, c-format
+msgid "%s: invalid shell `%s'\n"
+msgstr "%s: nieprawid³owa pow³oka `%s'\n"
+
+#: src/useradd.c:1333
+#, c-format
+msgid "%s: invalid user name `%s'\n"
+msgstr "%s: nieprawid³owa nazwa u¿ytkownika `%s'\n"
+
+#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225
+#, c-format
+msgid "%s: cannot rewrite password file\n"
+msgstr "%s: nie mogê przepisaæ pliku z has³ami\n"
+
+#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230
+#, c-format
+msgid "%s: cannot rewrite shadow password file\n"
+msgstr "%s: nie mogê przepisaæ pliku z ukrytymi has³ami\n"
+
+#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265
+#, c-format
+msgid "%s: unable to lock password file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z has³ami\n"
+
+#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269
+#, c-format
+msgid "%s: unable to open password file\n"
+msgstr "%s: nie mogê otworzyæ pliku z has³ami\n"
+
+#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274
+#, c-format
+msgid "%s: cannot lock shadow password file\n"
+msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n"
+
+#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279
+#, c-format
+msgid "%s: cannot open shadow password file\n"
+msgstr "%s: nie mogê otworzyæ pliku z ukrytymi has³ami\n"
+
+#: src/useradd.c:1529 src/usermod.c:1366
+#, c-format
+msgid "%s: error adding authentication method\n"
+msgstr "%s: b³±d podczas dodawania metody uwierzytelniania\n"
+
+#: src/useradd.c:1552
+#, c-format
+msgid "%s: error adding new password entry\n"
+msgstr "%s: b³±d podczas dodawania nowego wpisu do pliku z has³ami\n"
+
+#: src/useradd.c:1567
+#, c-format
+msgid "%s: error updating password dbm entry\n"
+msgstr "%s: b³±d podczas aktualizacji wpisu dbm do pliku z has³ami\n"
+
+#: src/useradd.c:1583 src/usermod.c:1425
+#, c-format
+msgid "%s: error adding new shadow password entry\n"
+msgstr "%s: b³±d podczas dodawania nowego wpisu do pliku z ukrytymi has³ami\n"
+
+#: src/useradd.c:1599 src/usermod.c:1440
+#, c-format
+msgid "%s: error updating shadow passwd dbm entry\n"
+msgstr "%s: b³±d podczas aktualizacji wpisu dbm do pliku z ukrytymi has³ami\n"
+
+#: src/useradd.c:1631
+#, c-format
+msgid "%s: cannot create directory %s\n"
+msgstr "%s: nie mogê utworzyæ katalogu %s\n"
+
+#: src/useradd.c:1708 src/usermod.c:1203
+#, c-format
+msgid "%s: user %s exists\n"
+msgstr "%s: u¿ytkownik %s istnieje\n"
+
+#: src/useradd.c:1738
+#, c-format
+msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n"
+msgstr ""
+
+#: src/userdel.c:127
+#, c-format
+msgid "usage: %s [-r] name\n"
+msgstr "u¿ycie: %s [-r] nazwa\n"
+
+#: src/userdel.c:178 src/userdel.c:260
+#, c-format
+msgid "%s: error updating group entry\n"
+msgstr "%s: b³±d podczas aktualizacji wpisu grupy\n"
+
+#: src/userdel.c:188 src/userdel.c:269
+#, c-format
+msgid "%s: cannot update dbm group entry\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu dbm do pliku z grupami\n"
+
+#: src/userdel.c:215
+#, fuzzy, c-format
+msgid "%s: cannot remove dbm group entry\n"
+msgstr "%s: nie mogê zaktualizowaæ wpisu dbm do pliku z grupami\n"
+
+#: src/userdel.c:300
+#, c-format
+msgid "%s: cannot rewrite TCFS key file\n"
+msgstr "%s: nie mogê przepisaæ pliku klucza TCFS\n"
+
+#: src/userdel.c:380
+#, c-format
+msgid "%s: cannot lock TCFS key file\n"
+msgstr "%s: nie mogê zablokowaæ pliku klucza TCFS\n"
+
+#: src/userdel.c:384
+#, c-format
+msgid "%s: cannot open TCFS key file\n"
+msgstr "%s: nie mogê otworzyæ pliku klucza TCFS\n"
+
+#: src/userdel.c:393
+#, c-format
+msgid "%s: cannot open group file\n"
+msgstr "%s: nie mogê otworzyæ pliku z grupami\n"
+
+#: src/userdel.c:403
+#, c-format
+msgid "%s: cannot open shadow group file\n"
+msgstr "%s: nie mogê otworzyæ pliku z przes³oniêtymi grupami\n"
+
+#: src/userdel.c:434 src/userdel.c:449
+#, c-format
+msgid "%s: error deleting authentication\n"
+msgstr "%s: b³±d podczas usuwania informacji uwierzytelniaj±cej\n"
+
+#: src/userdel.c:458
+#, c-format
+msgid "%s: error deleting password entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu do pliku z has³ami\n"
+
+#: src/userdel.c:461
+#, c-format
+msgid "%s: error deleting shadow password entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu do pliku z ukrytymi has³ami\n"
+
+#: src/userdel.c:470
+#, c-format
+msgid "%s: error deleting TCFS entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu TCFS\n"
+
+#: src/userdel.c:483
+#, c-format
+msgid "%s: error deleting password dbm entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu dbm do pliku z has³ami\n"
+
+#: src/userdel.c:502
+#, c-format
+msgid "%s: error deleting shadow passwd dbm entry\n"
+msgstr "%s: b³±d podczas usuwania wpisy dbm z pliku z ukrytymi has³ami\n"
+
+#: src/userdel.c:543
+#, c-format
+msgid "%s: user %s is currently logged in\n"
+msgstr "%s: u¿ytkownik %s jest aktualnie zalogowany\n"
+
+#: src/userdel.c:660
+#, c-format
+msgid "%s: warning: %s not owned by %s, not removing\n"
+msgstr "%s: ostrze¿enie: w³a¶cicielem %s nie jest %s, nie usuwam\n"
+
+#: src/userdel.c:666
+#, c-format
+msgid "%s: warning: can't remove "
+msgstr "%s: ostrze¿enie: nie mogê usun±æ "
+
+#: src/userdel.c:741 src/usermod.c:994
+#, c-format
+msgid "%s: user %s does not exist\n"
+msgstr "%s: u¿ytkownik %s nie istnieje\n"
+
+#: src/userdel.c:755 src/usermod.c:1010
+#, c-format
+msgid "%s: user %s is a NIS user\n"
+msgstr "%s: u¿ytkownik %s jest u¿ytkownikiem NIS\n"
+
+#: src/userdel.c:792
+#, c-format
+msgid "%s: %s not owned by %s, not removing\n"
+msgstr "%s: w³a¶cicielem %s nie jest %s, nie usuwam\n"
+
+#: src/userdel.c:815
+#, c-format
+msgid "%s: not removing directory %s (would remove home of user %s)\n"
+msgstr "%s: nie usuwam katalogu %s (would remove home of user %s)\n"
+
+#: src/userdel.c:828
+#, c-format
+msgid "%s: error removing directory %s\n"
+msgstr "%s: b³±d podczas usuwania katalogu %s\n"
+
+#: src/usermod.c:317
+msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"
+msgstr "\t\t[-d kat_dom [-m]] [-s pow³oka] [-c komentarz] [-l nowa_nazwa]\n"
+
+#: src/usermod.c:323
+msgid "[-A {DEFAULT|program},... ] "
+msgstr "[-A {DEFAULT|program},... ] "
+
+#: src/usermod.c:325
+#, fuzzy
+msgid "[-p passwd] [-L|-U] name\n"
+msgstr "[-p has³o] nazwa\n"
+
+#: src/usermod.c:504
+#, c-format
+msgid "%s: out of memory in update_group\n"
+msgstr "%s: zabrak³o pamiêci w pdate_group\n"
+
+#: src/usermod.c:627
+#, c-format
+msgid "%s: out of memory in update_gshadow\n"
+msgstr "%s: zabrak³o pamiêci w update_gshadow\n"
+
+#: src/usermod.c:1180
+#, c-format
+msgid "%s: no flags given\n"
+msgstr "%s: nie podano flag\n"
+
+#: src/usermod.c:1187
+#, c-format
+msgid "%s: shadow passwords required for -e and -f\n"
+msgstr "%s: ukryte has³a wymagane dla -e i -f\n"
+
+#: src/usermod.c:1208
+#, c-format
+msgid "%s: uid %ld is not unique\n"
+msgstr "%s: uid %ld nie jest niepowtarzalny\n"
+
+#: src/usermod.c:1356
+#, c-format
+msgid "%s: error deleting authentication method\n"
+msgstr "%s: b³±d podczas usuwania metody uwierzytelniania\n"
+
+#: src/usermod.c:1376
+#, c-format
+msgid "%s: error changing authentication method\n"
+msgstr "%s: b³±d podczas zmiany metody uwierzytelniania\n"
+
+#: src/usermod.c:1393
+#, c-format
+msgid "%s: error changing password entry\n"
+msgstr "%s: b³±d podczas zmiany wpisu w pliku z has³ami\n"
+
+#: src/usermod.c:1399
+#, c-format
+msgid "%s: error removing password entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu z pliku z has³ami\n"
+
+#: src/usermod.c:1407
+#, c-format
+msgid "%s: error adding password dbm entry\n"
+msgstr "%s: b³±d podczas dodawania wpisu dbm do pliku z has³ami\n"
+
+#: src/usermod.c:1414
+#, c-format
+msgid "%s: error removing passwd dbm entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu dbm z pliku z has³ami\n"
+
+#: src/usermod.c:1431
+#, c-format
+msgid "%s: error removing shadow password entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu z pliku z ukrytymi has³ami\n"
+
+#: src/usermod.c:1446
+#, c-format
+msgid "%s: error removing shadow passwd dbm entry\n"
+msgstr "%s: b³±d podczas usuwania wpisu dbm z pliku z ukrytymi has³ami\n"
+
+#: src/usermod.c:1477
+#, c-format
+msgid "%s: directory %s exists\n"
+msgstr "%s: katalog %s isnieje\n"
+
+#: src/usermod.c:1484
+#, c-format
+msgid "%s: can't create %s\n"
+msgstr "%s: nie mogê utworzyæ %s\n"
+
+#: src/usermod.c:1490
+#, c-format
+msgid "%s: can't chown %s\n"
+msgstr "%s: nie mogê zmieniæ w³a¶ciciela %s\n"
+
+#: src/usermod.c:1506
+#, c-format
+msgid "%s: cannot rename directory %s to %s\n"
+msgstr "%s: nie mogê zmieniæ nazwy katalogu z %s na %s\n"
+
+#. better leave it alone
+#: src/usermod.c:1603
+#, c-format
+msgid "%s: warning: %s not owned by %s\n"
+msgstr "%s: ostrze¿enie: w³a¶cicielem %s nie jest %s\n"
+
+#: src/usermod.c:1609
+msgid "failed to change mailbox owner"
+msgstr "nie powiod³a siê zmiana w³a¶ciciela skrzynki pocztowej"
+
+#: src/usermod.c:1616
+msgid "failed to rename mailbox"
+msgstr "zmiana nazwy skrzynki pocztowej nie powiod³a siê"
+
+#: src/vipw.c:102
+#, c-format
+msgid ""
+"\n"
+"%s: %s is unchanged\n"
+msgstr ""
+"\n"
+"%s: %s jest niezmieniony\n"
+
+#: src/vipw.c:127
+#, fuzzy
+msgid "Couldn't lock file"
+msgstr "%s: nie mogê usun±c blokady z pliku\n"
+
+#: src/vipw.c:134
+msgid "Couldn't make backup"
+msgstr ""
+
+#: src/vipw.c:187
+#, c-format
+msgid "%s: can't restore %s: %s (your changes are in %s)\n"
+msgstr "%s: nie mogê odzyskaæ %s: %s (twoje zmiany s± w %s)\n"
+
+#: src/vipw.c:226
+msgid ""
+"Usage:\n"
+"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n"
+"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n"
+msgstr ""
+"U¿ycie:\n"
+"`vipw' edytuje /etc/passwd `vipw -s' edytuje /etc/shadow\n"
+"`vigr' edytuje /etc/group `vigr -s' edytuje /etc/gshadow\n"
+
+#~ msgid "Incorrect password for %s.\n"
+#~ msgstr "Nieprawid³owe has³o dla %s.\n"
+
+#~ msgid "group not found\n"
+#~ msgstr "grupa nie znaleziona\n"
diff --git a/current/po/shadow.pot b/current/po/shadow.pot
new file mode 100644
index 00000000..7faa7116
--- /dev/null
+++ b/current/po/shadow.pot
@@ -0,0 +1,2368 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2000-09-02 20:40+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: libmisc/addgrps.c:60
+#, c-format
+msgid "Warning: unknown group %s\n"
+msgstr ""
+
+#: libmisc/addgrps.c:71
+msgid "Warning: too many groups\n"
+msgstr ""
+
+#: libmisc/age.c:104
+msgid "Your password has expired."
+msgstr ""
+
+#: libmisc/age.c:107
+msgid "Your password is inactive."
+msgstr ""
+
+#: libmisc/age.c:110
+msgid "Your login has expired."
+msgstr ""
+
+#: libmisc/age.c:127
+msgid " Contact the system administrator.\n"
+msgstr ""
+
+#: libmisc/age.c:130
+msgid " Choose a new password.\n"
+msgstr ""
+
+#: libmisc/age.c:228
+#, c-format
+msgid "Your password will expire in %ld days.\n"
+msgstr ""
+
+#: libmisc/age.c:230
+msgid "Your password will expire tomorrow.\n"
+msgstr ""
+
+#: libmisc/age.c:232
+msgid "Your password will expire today.\n"
+msgstr ""
+
+#: libmisc/chowntty.c:110
+#, c-format
+msgid "Unable to change tty %s"
+msgstr ""
+
+#: libmisc/env.c:160
+msgid "Environment overflow\n"
+msgstr ""
+
+#: libmisc/env.c:200
+#, c-format
+msgid "You may not change $%s\n"
+msgstr ""
+
+#: libmisc/failure.c:238
+#, c-format
+msgid "%d %s since last login. Last was %s on %s.\n"
+msgstr ""
+
+#: libmisc/failure.c:239
+msgid "failures"
+msgstr ""
+
+#: libmisc/failure.c:239
+msgid "failure"
+msgstr ""
+
+#: libmisc/limits.c:397
+msgid "Too many logins.\n"
+msgstr ""
+
+#: libmisc/login_desrpc.c:63
+#, c-format
+msgid "Password does not decrypt secret key for %s.\n"
+msgstr ""
+
+#: libmisc/login_desrpc.c:69
+#, c-format
+msgid "Could not set %s's secret key: is the keyserv daemon running?\n"
+msgstr ""
+
+#: libmisc/mail.c:62 libmisc/mail.c:77
+msgid "You have new mail."
+msgstr ""
+
+#: libmisc/mail.c:73
+msgid "No mail."
+msgstr ""
+
+#: libmisc/mail.c:75
+msgid "You have mail."
+msgstr ""
+
+#: libmisc/obscure.c:281 src/passwd.c:309
+#, c-format
+msgid "Bad password: %s. "
+msgstr ""
+
+#: libmisc/pam_pass.c:42
+#, c-format
+msgid "passwd: pam_start() failed, error %d\n"
+msgstr ""
+
+#: libmisc/pam_pass.c:49
+#, c-format
+msgid "passwd: %s\n"
+msgstr ""
+
+#: libmisc/setupenv.c:205
+#, c-format
+msgid "Unable to cd to \"%s\"\n"
+msgstr ""
+
+#: libmisc/setupenv.c:213
+msgid "No directory, logging in with HOME=/"
+msgstr ""
+
+#: libmisc/shell.c:78
+#, c-format
+msgid "Executing shell %s\n"
+msgstr ""
+
+#.
+#. * Obviously something is really wrong - I can't figure out
+#. * how to execute this stupid shell, so I might as well give
+#. * up in disgust ...
+#.
+#: libmisc/shell.c:122
+#, c-format
+msgid "Cannot execute %s"
+msgstr ""
+
+#: libmisc/suauth.c:99
+msgid "Access to su to that account DENIED.\n"
+msgstr ""
+
+#: libmisc/suauth.c:106
+msgid "Password authentication bypassed.\n"
+msgstr ""
+
+#: libmisc/suauth.c:113
+msgid "Please enter your OWN password as authentication.\n"
+msgstr ""
+
+#: libmisc/sub.c:61
+#, c-format
+msgid "Invalid root directory \"%s\"\n"
+msgstr ""
+
+#: libmisc/sub.c:73
+#, c-format
+msgid "Can't change root directory to \"%s\"\n"
+msgstr ""
+
+#: libmisc/xmalloc.c:28
+#, c-format
+msgid "malloc(%d) failed\n"
+msgstr ""
+
+#: lib/dialchk.c:71
+msgid "Dialup Password: "
+msgstr ""
+
+#: lib/getdef.c:253
+msgid "Could not allocate space for config info.\n"
+msgstr ""
+
+#.
+#. * Item was never found.
+#.
+#: lib/getdef.c:307
+#, c-format
+msgid "configuration error - unknown item '%s' (notify administrator)\n"
+msgstr ""
+
+#: lib/getdef.c:394
+#, c-format
+msgid "error - lookup '%s' failed\n"
+msgstr ""
+
+#: lib/getdef.c:402
+#, c-format
+msgid "%s not found\n"
+msgstr ""
+
+#.
+#. * get the password from her, and set the salt for
+#. * the decryption from the group file.
+#.
+#: lib/pwauth.c:54 src/newgrp.c:305
+msgid "Password: "
+msgstr ""
+
+#: lib/pwauth.c:56
+#, c-format
+msgid "%s's Password: "
+msgstr ""
+
+#: lib/pwauth.c:270
+msgid "(Echo on) "
+msgstr ""
+
+#: lib/strerror.c:20
+#, c-format
+msgid "Unknown error %d"
+msgstr ""
+
+#: src/chage.c:156
+#, c-format
+msgid ""
+"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n"
+" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"
+msgstr ""
+
+#: src/chage.c:158
+#, c-format
+msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"
+msgstr ""
+
+#: src/chage.c:193
+msgid ""
+"Enter the new value, or press return for the default\n"
+"\n"
+msgstr ""
+
+#: src/chage.c:196
+msgid "Minimum Password Age"
+msgstr ""
+
+#: src/chage.c:201
+msgid "Maximum Password Age"
+msgstr ""
+
+#: src/chage.c:207
+msgid "Last Password Change (YYYY-MM-DD)"
+msgstr ""
+
+#: src/chage.c:216
+msgid "Password Expiration Warning"
+msgstr ""
+
+#: src/chage.c:221
+msgid "Password Inactive"
+msgstr ""
+
+#: src/chage.c:227
+msgid "Account Expiration Date (YYYY-MM-DD)"
+msgstr ""
+
+#.
+#. * Start with the easy numbers - the number of days before the
+#. * password can be changed, the number of days after which the
+#. * password must be chaged, the number of days before the
+#. * password expires that the user is told, and the number of
+#. * days after the password expires that the account becomes
+#. * unusable.
+#.
+#: src/chage.c:281
+#, c-format
+msgid "Minimum:\t%ld\n"
+msgstr ""
+
+#: src/chage.c:282
+#, c-format
+msgid "Maximum:\t%ld\n"
+msgstr ""
+
+#: src/chage.c:284
+#, c-format
+msgid "Warning:\t%ld\n"
+msgstr ""
+
+#: src/chage.c:285
+#, c-format
+msgid "Inactive:\t%ld\n"
+msgstr ""
+
+#.
+#. * The "last change" date is either "Never" or the date the
+#. * password was last modified. The date is the number of
+#. * days since 1/1/1970.
+#.
+#: src/chage.c:294
+msgid "Last Change:\t\t"
+msgstr ""
+
+#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340
+msgid "Never\n"
+msgstr ""
+
+#.
+#. * The password expiration date is determined from the last
+#. * change date plus the number of days the password is valid
+#. * for.
+#.
+#: src/chage.c:308
+msgid "Password Expires:\t"
+msgstr ""
+
+#.
+#. * The account becomes inactive if the password is expired
+#. * for more than "inactdays". The expiration date is calculated
+#. * and the number of inactive days is added. The resulting date
+#. * is when the active will be disabled.
+#.
+#: src/chage.c:324
+msgid "Password Inactive:\t"
+msgstr ""
+
+#.
+#. * The account will expire on the given date regardless of the
+#. * password expiring or not.
+#.
+#: src/chage.c:338
+msgid "Account Expires:\t"
+msgstr ""
+
+#: src/chage.c:486
+#, c-format
+msgid "%s: do not include \"l\" with other flags\n"
+msgstr ""
+
+#: src/chage.c:498 src/chage.c:610 src/login.c:529
+#, c-format
+msgid "%s: permission denied\n"
+msgstr ""
+
+#: src/chage.c:510 src/chpasswd.c:120
+#, c-format
+msgid "%s: can't lock password file\n"
+msgstr ""
+
+#: src/chage.c:516 src/chpasswd.c:124
+#, c-format
+msgid "%s: can't open password file\n"
+msgstr ""
+
+#: src/chage.c:523
+#, c-format
+msgid "%s: unknown user: %s\n"
+msgstr ""
+
+#: src/chage.c:542
+#, c-format
+msgid "%s: can't lock shadow password file\n"
+msgstr ""
+
+#: src/chage.c:549
+#, c-format
+msgid "%s: can't open shadow password file\n"
+msgstr ""
+
+#: src/chage.c:631
+#, c-format
+msgid "Changing the aging information for %s\n"
+msgstr ""
+
+#: src/chage.c:633
+#, c-format
+msgid "%s: error changing fields\n"
+msgstr ""
+
+#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183
+#, c-format
+msgid "%s: can't update password file\n"
+msgstr ""
+
+#: src/chage.c:690 src/pwunconv.c:178
+#, c-format
+msgid "%s: can't update shadow password file\n"
+msgstr ""
+
+#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409
+#: src/passwd.c:825 src/passwd.c:926
+msgid "Error updating the DBM password entry.\n"
+msgstr ""
+
+#: src/chage.c:771
+#, c-format
+msgid "%s: can't rewrite shadow password file\n"
+msgstr ""
+
+#: src/chage.c:785
+#, c-format
+msgid "%s: can't rewrite password file\n"
+msgstr ""
+
+#: src/chage.c:836
+#, c-format
+msgid "%s: no aging information present\n"
+msgstr ""
+
+#: src/chfn.c:107
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n"
+"\t[ -h home_ph ] [ -o other ] [ user ]\n"
+msgstr ""
+
+#: src/chfn.c:111
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"
+msgstr ""
+
+#: src/chfn.c:163 src/chsh.c:119
+msgid "Enter the new value, or press return for the default\n"
+msgstr ""
+
+#: src/chfn.c:166
+msgid "Full Name"
+msgstr ""
+
+#: src/chfn.c:168
+#, c-format
+msgid "\tFull Name: %s\n"
+msgstr ""
+
+#: src/chfn.c:171
+msgid "Room Number"
+msgstr ""
+
+#: src/chfn.c:173
+#, c-format
+msgid "\tRoom Number: %s\n"
+msgstr ""
+
+#: src/chfn.c:176
+msgid "Work Phone"
+msgstr ""
+
+#: src/chfn.c:178
+#, c-format
+msgid "\tWork Phone: %s\n"
+msgstr ""
+
+#: src/chfn.c:181
+msgid "Home Phone"
+msgstr ""
+
+#: src/chfn.c:183
+#, c-format
+msgid "\tHome Phone: %s\n"
+msgstr ""
+
+#: src/chfn.c:186
+msgid "Other"
+msgstr ""
+
+#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330
+#: src/chfn.c:391 src/passwd.c:1226
+#, c-format
+msgid "%s: Permission denied.\n"
+msgstr ""
+
+#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277
+#, c-format
+msgid "%s: Unknown user %s\n"
+msgstr ""
+
+#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207
+#, c-format
+msgid "%s: Cannot determine your user name.\n"
+msgstr ""
+
+#: src/chfn.c:373 src/chsh.c:250
+#, c-format
+msgid "%s: cannot change user `%s' on NIS client.\n"
+msgstr ""
+
+#: src/chfn.c:378 src/chsh.c:257
+#, c-format
+msgid "%s: `%s' is the NIS master for this client.\n"
+msgstr ""
+
+#: src/chfn.c:453
+#, c-format
+msgid "Changing the user information for %s\n"
+msgstr ""
+
+#: src/chfn.c:462
+#, c-format
+msgid "%s: invalid name: \"%s\"\n"
+msgstr ""
+
+#: src/chfn.c:467
+#, c-format
+msgid "%s: invalid room number: \"%s\"\n"
+msgstr ""
+
+#: src/chfn.c:472
+#, c-format
+msgid "%s: invalid work phone: \"%s\"\n"
+msgstr ""
+
+#: src/chfn.c:477
+#, c-format
+msgid "%s: invalid home phone: \"%s\"\n"
+msgstr ""
+
+#: src/chfn.c:482
+#, c-format
+msgid "%s: \"%s\" contains illegal characters\n"
+msgstr ""
+
+#: src/chfn.c:494
+#, c-format
+msgid "%s: fields too long\n"
+msgstr ""
+
+#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388
+msgid "Cannot change ID to root.\n"
+msgstr ""
+
+#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880
+msgid "Cannot lock the password file; try again later.\n"
+msgstr ""
+
+#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885
+msgid "Cannot open the password file.\n"
+msgstr ""
+
+#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313
+#, c-format
+msgid "%s: %s not found in /etc/passwd\n"
+msgstr ""
+
+#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920
+#: src/passwd.c:960
+msgid "Error updating the password entry.\n"
+msgstr ""
+
+#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933
+msgid "Cannot commit password file changes.\n"
+msgstr ""
+
+#: src/chfn.c:592 src/chsh.c:431
+msgid "Cannot unlock the password file.\n"
+msgstr ""
+
+#: src/chpasswd.c:76
+#, c-format
+msgid "usage: %s [-e]\n"
+msgstr ""
+
+#: src/chpasswd.c:132 src/pwconv.c:104
+#, c-format
+msgid "%s: can't lock shadow file\n"
+msgstr ""
+
+#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118
+#: src/pwunconv.c:123
+#, c-format
+msgid "%s: can't open shadow file\n"
+msgstr ""
+
+#: src/chpasswd.c:159 src/newusers.c:415
+#, c-format
+msgid "%s: line %d: line too long\n"
+msgstr ""
+
+#: src/chpasswd.c:179
+#, c-format
+msgid "%s: line %d: missing new password\n"
+msgstr ""
+
+#: src/chpasswd.c:195
+#, c-format
+msgid "%s: line %d: unknown user %s\n"
+msgstr ""
+
+#: src/chpasswd.c:247
+#, c-format
+msgid "%s: line %d: cannot update password entry\n"
+msgstr ""
+
+#: src/chpasswd.c:263 src/newusers.c:535
+#, c-format
+msgid "%s: error detected, changes ignored\n"
+msgstr ""
+
+#: src/chpasswd.c:274
+#, c-format
+msgid "%s: error updating shadow file\n"
+msgstr ""
+
+#: src/chpasswd.c:282
+#, c-format
+msgid "%s: error updating password file\n"
+msgstr ""
+
+#: src/chsh.c:105
+#, c-format
+msgid "Usage: %s [ -s shell ] [ name ]\n"
+msgstr ""
+
+#: src/chsh.c:120
+msgid "Login Shell"
+msgstr ""
+
+#: src/chsh.c:273 src/chsh.c:286
+#, c-format
+msgid "You may not change the shell for %s.\n"
+msgstr ""
+
+#: src/chsh.c:315
+#, c-format
+msgid "Changing the login shell for %s\n"
+msgstr ""
+
+#: src/chsh.c:327
+#, c-format
+msgid "%s: Invalid entry: %s\n"
+msgstr ""
+
+#: src/chsh.c:332
+#, c-format
+msgid "%s is an invalid shell.\n"
+msgstr ""
+
+#: src/dpasswd.c:69
+#, c-format
+msgid "Usage: %s [ -(a|d) ] shell\n"
+msgstr ""
+
+#: src/dpasswd.c:134
+msgid "Shell password: "
+msgstr ""
+
+#: src/dpasswd.c:140
+msgid "re-enter Shell password: "
+msgstr ""
+
+#: src/dpasswd.c:147
+#, c-format
+msgid "%s: Passwords do not match, try again.\n"
+msgstr ""
+
+#: src/dpasswd.c:167
+#, c-format
+msgid "%s: can't create %s"
+msgstr ""
+
+#: src/dpasswd.c:172
+#, c-format
+msgid "%s: can't open %s"
+msgstr ""
+
+#: src/dpasswd.c:200
+#, c-format
+msgid "%s: Shell %s not found.\n"
+msgstr ""
+
+#: src/expiry.c:84
+msgid "Usage: expiry { -f | -c }\n"
+msgstr ""
+
+#: src/expiry.c:137
+#, c-format
+msgid "%s: WARNING! Must be set-UID root!\n"
+msgstr ""
+
+#: src/expiry.c:148
+#, c-format
+msgid "%s: unknown user\n"
+msgstr ""
+
+#: src/faillog.c:79
+#, c-format
+msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"
+msgstr ""
+
+#: src/faillog.c:134 src/lastlog.c:94
+#, c-format
+msgid "Unknown User: %s\n"
+msgstr ""
+
+#: src/faillog.c:215
+msgid "Username Failures Maximum Latest\n"
+msgstr ""
+
+#: src/faillog.c:232
+#, c-format
+msgid " %s on %s"
+msgstr ""
+
+#: src/faillog.c:236
+#, c-format
+msgid " [%lds left]"
+msgstr ""
+
+#: src/faillog.c:239
+#, c-format
+msgid " [%lds lock]"
+msgstr ""
+
+#: src/gpasswd.c:89
+#, c-format
+msgid "usage: %s [-r|-R] group\n"
+msgstr ""
+
+#: src/gpasswd.c:90
+#, c-format
+msgid " %s [-a user] group\n"
+msgstr ""
+
+#: src/gpasswd.c:91
+#, c-format
+msgid " %s [-d user] group\n"
+msgstr ""
+
+#: src/gpasswd.c:93
+#, c-format
+msgid " %s [-A user,...] [-M user,...] group\n"
+msgstr ""
+
+#: src/gpasswd.c:96
+#, c-format
+msgid " %s [-M user,...] group\n"
+msgstr ""
+
+#: src/gpasswd.c:160 src/gpasswd.c:245
+#, c-format
+msgid "%s: unknown user %s\n"
+msgstr ""
+
+#: src/gpasswd.c:172
+msgid "Permission denied.\n"
+msgstr ""
+
+#: src/gpasswd.c:257
+#, c-format
+msgid "%s: shadow group passwords required for -A\n"
+msgstr ""
+
+#: src/gpasswd.c:308
+msgid "Who are you?\n"
+msgstr ""
+
+#: src/gpasswd.c:328 src/newgrp.c:251
+#, c-format
+msgid "unknown group: %s\n"
+msgstr ""
+
+#: src/gpasswd.c:436
+#, c-format
+msgid "Adding user %s to group %s\n"
+msgstr ""
+
+#: src/gpasswd.c:453
+#, c-format
+msgid "Removing user %s from group %s\n"
+msgstr ""
+
+#: src/gpasswd.c:466
+#, c-format
+msgid "%s: unknown member %s\n"
+msgstr ""
+
+#: src/gpasswd.c:513
+#, c-format
+msgid "%s: Not a tty\n"
+msgstr ""
+
+#.
+#. * A new password is to be entered and it must be encrypted,
+#. * etc. The password will be prompted for twice, and both
+#. * entries must be identical. There is no need to validate
+#. * the old password since the invoker is either the group
+#. * owner, or root.
+#.
+#: src/gpasswd.c:535
+#, c-format
+msgid "Changing the password for group %s\n"
+msgstr ""
+
+#: src/gpasswd.c:538
+msgid "New Password: "
+msgstr ""
+
+#: src/gpasswd.c:543 src/passwd.c:422
+msgid "Re-enter new password: "
+msgstr ""
+
+#: src/gpasswd.c:555
+msgid "They don't match; try again"
+msgstr ""
+
+#: src/gpasswd.c:559
+#, c-format
+msgid "%s: Try again later\n"
+msgstr ""
+
+#: src/gpasswd.c:590
+#, c-format
+msgid "%s: can't get lock\n"
+msgstr ""
+
+#: src/gpasswd.c:596
+#, c-format
+msgid "%s: can't get shadow lock\n"
+msgstr ""
+
+#: src/gpasswd.c:602
+#, c-format
+msgid "%s: can't open file\n"
+msgstr ""
+
+#: src/gpasswd.c:614
+#, c-format
+msgid "%s: can't update entry\n"
+msgstr ""
+
+#: src/gpasswd.c:620
+#, c-format
+msgid "%s: can't update shadow entry\n"
+msgstr ""
+
+#: src/gpasswd.c:626
+#, c-format
+msgid "%s: can't re-write file\n"
+msgstr ""
+
+#: src/gpasswd.c:632
+#, c-format
+msgid "%s: can't re-write shadow file\n"
+msgstr ""
+
+#: src/gpasswd.c:640
+#, c-format
+msgid "%s: can't unlock file\n"
+msgstr ""
+
+#: src/gpasswd.c:645
+#, c-format
+msgid "%s: can't update DBM files\n"
+msgstr ""
+
+#: src/gpasswd.c:652
+#, c-format
+msgid "%s: can't update DBM shadow files\n"
+msgstr ""
+
+#: src/groupadd.c:105
+msgid "usage: groupadd [-g gid [-o]] group\n"
+msgstr ""
+
+#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230
+#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675
+#, c-format
+msgid "%s: error adding new group entry\n"
+msgstr ""
+
+#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942
+#: src/usermod.c:551 src/usermod.c:687
+#, c-format
+msgid "%s: cannot add new dbm group entry\n"
+msgstr ""
+
+#: src/groupadd.c:258 src/useradd.c:996
+#, c-format
+msgid "%s: name %s is not unique\n"
+msgstr ""
+
+#: src/groupadd.c:273
+#, c-format
+msgid "%s: gid %ld is not unique\n"
+msgstr ""
+
+#: src/groupadd.c:297
+#, c-format
+msgid "%s: can't get unique gid\n"
+msgstr ""
+
+#.
+#. * All invalid group names land here.
+#.
+#: src/groupadd.c:321 src/groupmod.c:341
+#, c-format
+msgid "%s: %s is a not a valid group name\n"
+msgstr ""
+
+#: src/groupadd.c:350 src/groupmod.c:367
+#, c-format
+msgid "%s: invalid group %s\n"
+msgstr ""
+
+#: src/groupadd.c:367 src/useradd.c:1272
+#, c-format
+msgid "%s: -O requires NAME=VALUE\n"
+msgstr ""
+
+#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381
+#: src/userdel.c:303 src/usermod.c:563
+#, c-format
+msgid "%s: cannot rewrite group file\n"
+msgstr ""
+
+#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389
+#: src/userdel.c:309 src/usermod.c:700
+#, c-format
+msgid "%s: cannot rewrite shadow group file\n"
+msgstr ""
+
+#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389
+#, c-format
+msgid "%s: unable to lock group file\n"
+msgstr ""
+
+#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432
+#, c-format
+msgid "%s: unable to open group file\n"
+msgstr ""
+
+#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398
+#, c-format
+msgid "%s: unable to lock shadow group file\n"
+msgstr ""
+
+#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442
+#, c-format
+msgid "%s: unable to open shadow group file\n"
+msgstr ""
+
+#: src/groupadd.c:518
+#, c-format
+msgid "%s: group %s exists\n"
+msgstr ""
+
+#: src/groupdel.c:86
+msgid "usage: groupdel group\n"
+msgstr ""
+
+#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234
+#, c-format
+msgid "%s: error removing group entry\n"
+msgstr ""
+
+#: src/groupdel.c:116 src/groupmod.c:206
+#, c-format
+msgid "%s: error removing group dbm entry\n"
+msgstr ""
+
+#: src/groupdel.c:131
+#, c-format
+msgid "%s: error removing shadow group entry\n"
+msgstr ""
+
+#: src/groupdel.c:144 src/groupmod.c:252
+#, c-format
+msgid "%s: error removing shadow group dbm entry\n"
+msgstr ""
+
+#.
+#. * Can't remove the group.
+#.
+#: src/groupdel.c:248
+#, c-format
+msgid "%s: cannot remove user's primary group.\n"
+msgstr ""
+
+#: src/groupdel.c:305 src/groupmod.c:501
+#, c-format
+msgid "%s: group %s does not exist\n"
+msgstr ""
+
+#: src/groupdel.c:319 src/groupmod.c:517
+#, c-format
+msgid "%s: group %s is a NIS group\n"
+msgstr ""
+
+#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016
+#, c-format
+msgid "%s: %s is the NIS master\n"
+msgstr ""
+
+#: src/groupmod.c:105
+msgid "usage: groupmod [-g gid [-o]] [-n name] group\n"
+msgstr ""
+
+#: src/groupmod.c:165
+#, c-format
+msgid "%s: %s not found in /etc/group\n"
+msgstr ""
+
+#: src/groupmod.c:246
+#, c-format
+msgid "%s: cannot add new dbm shadow group entry\n"
+msgstr ""
+
+#: src/groupmod.c:299
+#, c-format
+msgid "%s: %ld is not a unique gid\n"
+msgstr ""
+
+#: src/groupmod.c:330
+#, c-format
+msgid "%s: %s is not a unique name\n"
+msgstr ""
+
+#: src/groups.c:62
+#, c-format
+msgid "unknown user %s\n"
+msgstr ""
+
+#: src/grpck.c:98
+#, c-format
+msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n"
+msgstr ""
+
+#: src/grpck.c:100
+#, c-format
+msgid "Usage: %s [ -r ] [ group ]\n"
+msgstr ""
+
+#: src/grpck.c:119 src/pwck.c:119
+msgid "No"
+msgstr ""
+
+#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225
+#, c-format
+msgid "%s: cannot lock file %s\n"
+msgstr ""
+
+#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241
+#: src/pwck.c:250
+#, c-format
+msgid "%s: cannot open file %s\n"
+msgstr ""
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:298
+msgid "invalid group file entry\n"
+msgstr ""
+
+#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517
+#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517
+#: src/pwck.c:541
+#, c-format
+msgid "delete line `%s'? "
+msgstr ""
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:361
+msgid "duplicate group entry\n"
+msgstr ""
+
+#: src/grpck.c:378
+#, c-format
+msgid "invalid group name `%s'\n"
+msgstr ""
+
+#: src/grpck.c:388
+#, c-format
+msgid "group %s: bad GID (%d)\n"
+msgstr ""
+
+#: src/grpck.c:414
+#, c-format
+msgid "group %s: no user %s\n"
+msgstr ""
+
+#: src/grpck.c:416 src/grpck.c:585
+#, c-format
+msgid "delete member `%s'? "
+msgstr ""
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:453
+msgid "invalid shadow group file entry\n"
+msgstr ""
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:516
+msgid "duplicate shadow group entry\n"
+msgstr ""
+
+#: src/grpck.c:533
+msgid "no matching group file entry\n"
+msgstr ""
+
+#: src/grpck.c:553
+#, c-format
+msgid "shadow group %s: no administrative user %s\n"
+msgstr ""
+
+#: src/grpck.c:555
+#, c-format
+msgid "delete administrative member `%s'? "
+msgstr ""
+
+#: src/grpck.c:583
+#, c-format
+msgid "shadow group %s: no user %s\n"
+msgstr ""
+
+#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580
+#, c-format
+msgid "%s: cannot update file %s\n"
+msgstr ""
+
+#: src/grpck.c:640 src/pwck.c:606
+#, c-format
+msgid "%s: the files have been updated; run mkpasswd\n"
+msgstr ""
+
+#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611
+#, c-format
+msgid "%s: no changes\n"
+msgstr ""
+
+#: src/grpck.c:644 src/pwck.c:610
+#, c-format
+msgid "%s: the files have been updated\n"
+msgstr ""
+
+#: src/grpconv.c:62 src/grpunconv.c:63
+#, c-format
+msgid "%s: can't lock group file\n"
+msgstr ""
+
+#: src/grpconv.c:67 src/grpunconv.c:68
+#, c-format
+msgid "%s: can't open group file\n"
+msgstr ""
+
+#: src/grpconv.c:72 src/grpunconv.c:73
+#, c-format
+msgid "%s: can't lock shadow group file\n"
+msgstr ""
+
+#: src/grpconv.c:77 src/grpunconv.c:78
+#, c-format
+msgid "%s: can't open shadow group file\n"
+msgstr ""
+
+#.
+#. * This shouldn't happen (the entry exists) but...
+#.
+#: src/grpconv.c:93
+#, c-format
+msgid "%s: can't remove shadow group %s\n"
+msgstr ""
+
+#: src/grpconv.c:134 src/pwconv.c:160
+#, c-format
+msgid "%s: can't update shadow entry for %s\n"
+msgstr ""
+
+#: src/grpconv.c:143 src/grpunconv.c:94
+#, c-format
+msgid "%s: can't update entry for group %s\n"
+msgstr ""
+
+#: src/grpconv.c:150 src/grpunconv.c:102
+#, c-format
+msgid "%s: can't update shadow group file\n"
+msgstr ""
+
+#: src/grpconv.c:154 src/grpunconv.c:107
+#, c-format
+msgid "%s: can't update group file\n"
+msgstr ""
+
+#: src/grpconv.c:169 src/grpunconv.c:128
+#, c-format
+msgid "%s: not configured for shadow group support.\n"
+msgstr ""
+
+#: src/grpunconv.c:112
+#, c-format
+msgid "%s: can't delete shadow group file\n"
+msgstr ""
+
+#: src/id.c:56
+msgid "usage: id [ -a ]\n"
+msgstr ""
+
+#: src/id.c:58
+msgid "usage: id\n"
+msgstr ""
+
+#: src/id.c:118
+#, c-format
+msgid "uid=%d(%s)"
+msgstr ""
+
+#: src/id.c:120
+#, c-format
+msgid "uid=%d"
+msgstr ""
+
+#: src/id.c:124
+#, c-format
+msgid " gid=%d(%s)"
+msgstr ""
+
+#: src/id.c:126
+#, c-format
+msgid " gid=%d"
+msgstr ""
+
+#: src/id.c:136
+#, c-format
+msgid " euid=%d(%s)"
+msgstr ""
+
+#: src/id.c:138
+#, c-format
+msgid " euid=%d"
+msgstr ""
+
+#: src/id.c:143
+#, c-format
+msgid " egid=%d(%s)"
+msgstr ""
+
+#: src/id.c:145
+#, c-format
+msgid " egid=%d"
+msgstr ""
+
+#.
+#. * Start off the group message. It will be of the format
+#. *
+#. * groups=###(aaa),###(aaa),###(aaa)
+#. *
+#. * where "###" is a numerical value and "aaa" is the
+#. * corresponding name for each respective numerical value.
+#.
+#: src/id.c:166
+msgid " groups="
+msgstr ""
+
+#: src/lastlog.c:167
+msgid "Username Port From Latest\n"
+msgstr ""
+
+#: src/lastlog.c:169
+msgid "Username Port Latest\n"
+msgstr ""
+
+#: src/lastlog.c:183
+msgid "**Never logged in**"
+msgstr ""
+
+#: src/login.c:198
+#, c-format
+msgid "usage: %s [-p] [name]\n"
+msgstr ""
+
+#: src/login.c:201
+#, c-format
+msgid " %s [-p] [-h host] [-f name]\n"
+msgstr ""
+
+#: src/login.c:203
+#, c-format
+msgid " %s [-p] -r host\n"
+msgstr ""
+
+#: src/login.c:286
+msgid "Invalid login time\n"
+msgstr ""
+
+#: src/login.c:341
+msgid ""
+"\n"
+"System closed for routine maintenance\n"
+msgstr ""
+
+#: src/login.c:351
+msgid ""
+"\n"
+"[Disconnect bypassed -- root login allowed.]\n"
+msgstr ""
+
+#: src/login.c:390
+#, c-format
+msgid ""
+"\n"
+"Login timed out after %d seconds.\n"
+msgstr ""
+
+#: src/login.c:692
+#, c-format
+msgid " on `%.100s' from `%.200s'"
+msgstr ""
+
+#: src/login.c:694
+#, c-format
+msgid " on `%.100s'"
+msgstr ""
+
+#: src/login.c:834
+#, c-format
+msgid ""
+"\n"
+"%s login: "
+msgstr ""
+
+#: src/login.c:836
+msgid "login: "
+msgstr ""
+
+#: src/login.c:1026 src/sulogin.c:231
+msgid "Login incorrect"
+msgstr ""
+
+#: src/login.c:1213
+msgid "Warning: login re-enabled after temporary lockout.\n"
+msgstr ""
+
+#: src/login.c:1223
+#, c-format
+msgid "Last login: %s on %s"
+msgstr ""
+
+#: src/login.c:1226
+#, c-format
+msgid "Last login: %.19s on %s"
+msgstr ""
+
+#: src/login.c:1231
+#, c-format
+msgid " from %.*s"
+msgstr ""
+
+#: src/login.c:1303
+msgid "Starting rad_login\n"
+msgstr ""
+
+#: src/mkpasswd.c:49
+#, c-format
+msgid "%s: no DBM database on system - no action performed\n"
+msgstr ""
+
+#: src/mkpasswd.c:245 src/mkpasswd.c:249
+#, c-format
+msgid "%s: cannot overwrite file %s\n"
+msgstr ""
+
+#: src/mkpasswd.c:263
+#, c-format
+msgid "%s: cannot open DBM files for %s\n"
+msgstr ""
+
+#: src/mkpasswd.c:296
+#, c-format
+msgid "%s: the beginning with "
+msgstr ""
+
+#: src/mkpasswd.c:321
+#, c-format
+msgid "%s: error parsing line \"%s\"\n"
+msgstr ""
+
+#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332
+msgid "adding record for name "
+msgstr ""
+
+#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349
+#, c-format
+msgid "%s: error adding record for "
+msgstr ""
+
+#: src/mkpasswd.c:367
+#, c-format
+msgid "added %d entries, longest was %d\n"
+msgstr ""
+
+#: src/mkpasswd.c:382
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"
+msgstr ""
+
+#: src/mkpasswd.c:384
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n"
+msgstr ""
+
+#: src/mkpasswd.c:387
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g ] file\n"
+msgstr ""
+
+#: src/newgrp.c:66
+msgid "usage: newgrp [ - ] [ group ]\n"
+msgstr ""
+
+#: src/newgrp.c:68
+msgid "usage: sg group [[-c] command ]\n"
+msgstr ""
+
+#: src/newgrp.c:125
+#, c-format
+msgid "unknown uid: %d\n"
+msgstr ""
+
+#: src/newgrp.c:201
+#, c-format
+msgid "unknown gid: %ld\n"
+msgstr ""
+
+#: src/newgrp.c:245
+#, c-format
+msgid "unknown gid: %d\n"
+msgstr ""
+
+#: src/newgrp.c:323 src/newgrp.c:332
+msgid "Sorry.\n"
+msgstr ""
+
+#: src/newgrp.c:364
+msgid "too many groups\n"
+msgstr ""
+
+#: src/newusers.c:76
+#, c-format
+msgid "Usage: %s [ input ]\n"
+msgstr ""
+
+#: src/newusers.c:364
+#, c-format
+msgid "%s: can't lock /etc/passwd.\n"
+msgstr ""
+
+#: src/newusers.c:375
+#, c-format
+msgid "%s: can't lock files, try again later\n"
+msgstr ""
+
+#: src/newusers.c:390
+#, c-format
+msgid "%s: can't open files\n"
+msgstr ""
+
+#: src/newusers.c:435
+#, c-format
+msgid "%s: line %d: invalid line\n"
+msgstr ""
+
+#: src/newusers.c:453
+#, c-format
+msgid "%s: line %d: can't create GID\n"
+msgstr ""
+
+#: src/newusers.c:469
+#, c-format
+msgid "%s: line %d: can't create UID\n"
+msgstr ""
+
+#: src/newusers.c:481
+#, c-format
+msgid "%s: line %d: cannot find user %s\n"
+msgstr ""
+
+#: src/newusers.c:489
+#, c-format
+msgid "%s: line %d: can't update password\n"
+msgstr ""
+
+#: src/newusers.c:506
+#, c-format
+msgid "%s: line %d: mkdir failed\n"
+msgstr ""
+
+#: src/newusers.c:510
+#, c-format
+msgid "%s: line %d: chown failed\n"
+msgstr ""
+
+#: src/newusers.c:519
+#, c-format
+msgid "%s: line %d: can't update entry\n"
+msgstr ""
+
+#: src/newusers.c:550
+#, c-format
+msgid "%s: error updating files\n"
+msgstr ""
+
+#: src/passwd.c:239
+#, c-format
+msgid "usage: %s [ -f | -s ] [ name ]\n"
+msgstr ""
+
+#: src/passwd.c:242
+#, c-format
+msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"
+msgstr ""
+
+#: src/passwd.c:245
+#, c-format
+msgid " %s { -l | -u | -d | -S | -e } name\n"
+msgstr ""
+
+#: src/passwd.c:347
+#, c-format
+msgid "User %s has a TCFS key, his old password is required.\n"
+msgstr ""
+
+#: src/passwd.c:348
+msgid "You can use -t option to force the change.\n"
+msgstr ""
+
+#: src/passwd.c:354
+msgid "Old password: "
+msgstr ""
+
+#: src/passwd.c:361
+#, c-format
+msgid "Incorrect password for `%s'\n"
+msgstr ""
+
+#: src/passwd.c:374
+#, c-format
+msgid "Warning: user %s has a TCFS key.\n"
+msgstr ""
+
+#: src/passwd.c:392
+#, c-format
+msgid ""
+"Enter the new password (minimum of %d, maximum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"
+msgstr ""
+
+#: src/passwd.c:399
+msgid "New password: "
+msgstr ""
+
+#: src/passwd.c:409
+msgid "Try again.\n"
+msgstr ""
+
+#: src/passwd.c:418
+msgid ""
+"\n"
+"Warning: weak password (enter it again to use it anyway).\n"
+msgstr ""
+
+#: src/passwd.c:427
+msgid "They don't match; try again.\n"
+msgstr ""
+
+#: src/passwd.c:512 src/passwd.c:528
+#, c-format
+msgid "The password for %s cannot be changed.\n"
+msgstr ""
+
+#: src/passwd.c:556
+#, c-format
+msgid "Sorry, the password for %s cannot be changed yet.\n"
+msgstr ""
+
+#: src/passwd.c:693
+#, c-format
+msgid "%s: out of memory\n"
+msgstr ""
+
+#: src/passwd.c:845
+msgid "Cannot lock the TCFS key database; try again later\n"
+msgstr ""
+
+#: src/passwd.c:851
+msgid "Cannot open the TCFS key database.\n"
+msgstr ""
+
+#: src/passwd.c:857
+msgid "Error updating the TCFS key database.\n"
+msgstr ""
+
+#: src/passwd.c:862
+msgid "Cannot commit TCFS changes.\n"
+msgstr ""
+
+#: src/passwd.c:1069
+#, c-format
+msgid "%s: Cannot execute %s"
+msgstr ""
+
+#: src/passwd.c:1176
+#, c-format
+msgid "%s: repository %s not supported\n"
+msgstr ""
+
+#: src/passwd.c:1263
+#, c-format
+msgid "%s: Permission denied\n"
+msgstr ""
+
+#: src/passwd.c:1287
+#, c-format
+msgid "You may not change the password for %s.\n"
+msgstr ""
+
+#: src/passwd.c:1352
+#, c-format
+msgid "Changing password for %s\n"
+msgstr ""
+
+#: src/passwd.c:1356
+#, c-format
+msgid "The password for %s is unchanged.\n"
+msgstr ""
+
+#: src/passwd.c:1412
+msgid "Password changed.\n"
+msgstr ""
+
+#: src/pwck.c:98
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"
+msgstr ""
+
+#: src/pwck.c:100
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd ]\n"
+msgstr ""
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:285
+msgid "invalid password file entry\n"
+msgstr ""
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:347
+msgid "duplicate password entry\n"
+msgstr ""
+
+#: src/pwck.c:363
+#, c-format
+msgid "invalid user name `%s'\n"
+msgstr ""
+
+#: src/pwck.c:373
+#, c-format
+msgid "user %s: bad UID (%d)\n"
+msgstr ""
+
+#.
+#. * No primary group, just give a warning
+#.
+#: src/pwck.c:388
+#, c-format
+msgid "user %s: no group %d\n"
+msgstr ""
+
+#.
+#. * Home directory doesn't exist, give a warning
+#.
+#: src/pwck.c:403
+#, c-format
+msgid "user %s: directory %s does not exist\n"
+msgstr ""
+
+#.
+#. * Login shell doesn't exist, give a warning
+#.
+#: src/pwck.c:418
+#, c-format
+msgid "user %s: program %s does not exist\n"
+msgstr ""
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:454
+msgid "invalid shadow password file entry\n"
+msgstr ""
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:516
+msgid "duplicate shadow password entry\n"
+msgstr ""
+
+#.
+#. * Tell the user this entry has no matching
+#. * /etc/passwd entry and ask them to delete it.
+#.
+#: src/pwck.c:540
+msgid "no matching password file entry\n"
+msgstr ""
+
+#: src/pwck.c:557
+#, c-format
+msgid "user %s: last password change in the future\n"
+msgstr ""
+
+#: src/pwconv.c:94 src/pwunconv.c:108
+#, c-format
+msgid "%s: can't lock passwd file\n"
+msgstr ""
+
+#: src/pwconv.c:99 src/pwunconv.c:113
+#, c-format
+msgid "%s: can't open passwd file\n"
+msgstr ""
+
+#: src/pwconv.c:126
+#, c-format
+msgid "%s: can't remove shadow entry for %s\n"
+msgstr ""
+
+#: src/pwconv.c:169
+#, c-format
+msgid "%s: can't update passwd entry for %s\n"
+msgstr ""
+
+#: src/pwconv.c:176
+#, c-format
+msgid "%s: can't update shadow file\n"
+msgstr ""
+
+#: src/pwconv.c:180
+#, c-format
+msgid "%s: can't update passwd file\n"
+msgstr ""
+
+#: src/pwunconv.c:62
+#, c-format
+msgid "%s: Shadow passwords are not configured.\n"
+msgstr ""
+
+#: src/pwunconv.c:171
+#, c-format
+msgid "%s: can't update entry for user %s\n"
+msgstr ""
+
+#: src/pwunconv.c:188
+#, c-format
+msgid "%s: can't delete shadow password file\n"
+msgstr ""
+
+#: src/su.c:140
+msgid "Sorry."
+msgstr ""
+
+#: src/su.c:222
+#, c-format
+msgid "%s: must be run from a terminal\n"
+msgstr ""
+
+#: src/su.c:311
+#, c-format
+msgid "%s: pam_start: error %d\n"
+msgstr ""
+
+#: src/su.c:337
+#, c-format
+msgid "Unknown id: %s\n"
+msgstr ""
+
+#. access denied (-1) or unexpected value
+#: src/su.c:372 src/su.c:387
+#, c-format
+msgid "You are not authorized to su %s\n"
+msgstr ""
+
+#. require own password
+#: src/su.c:383
+msgid "(Enter your own password.)"
+msgstr ""
+
+#: src/su.c:404
+#, c-format
+msgid "%s: permission denied (shell).\n"
+msgstr ""
+
+#: src/su.c:428
+#, c-format
+msgid ""
+"%s: %s\n"
+"(Ignored)\n"
+msgstr ""
+
+#: src/su.c:628
+msgid "No shell\n"
+msgstr ""
+
+#. must be a password file!
+#: src/sulogin.c:136
+msgid "No password file\n"
+msgstr ""
+
+#.
+#. * Fail secure
+#.
+#: src/sulogin.c:178
+msgid "No password entry for 'root'\n"
+msgstr ""
+
+#.
+#. * Here we prompt for the root password, or if no password is
+#. * given we just exit.
+#.
+#. get a password for root
+#: src/sulogin.c:192
+msgid ""
+"\n"
+"Type control-d to proceed with normal startup,\n"
+"(or give root password for system maintenance):"
+msgstr ""
+
+#. make new environment active
+#: src/sulogin.c:241
+msgid "Entering System Maintenance Mode\n"
+msgstr ""
+
+#: src/useradd.c:243
+#, c-format
+msgid "%s: rebuild the group database\n"
+msgstr ""
+
+#: src/useradd.c:250
+#, c-format
+msgid "%s: rebuild the shadow group database\n"
+msgstr ""
+
+#: src/useradd.c:287 src/usermod.c:967
+#, c-format
+msgid "%s: invalid numeric argument `%s'\n"
+msgstr ""
+
+#: src/useradd.c:343
+#, c-format
+msgid "%s: unknown gid %s\n"
+msgstr ""
+
+#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254
+#: src/usermod.c:1098
+#, c-format
+msgid "%s: unknown group %s\n"
+msgstr ""
+
+#: src/useradd.c:418
+#, c-format
+msgid "group=%s,%ld basedir=%s skel=%s\n"
+msgstr ""
+
+#: src/useradd.c:421
+#, c-format
+msgid "shell=%s "
+msgstr ""
+
+#: src/useradd.c:423
+#, c-format
+msgid "inactive=%ld expire=%s"
+msgstr ""
+
+#: src/useradd.c:427
+#, c-format
+msgid "GROUP=%ld\n"
+msgstr ""
+
+#: src/useradd.c:428
+#, c-format
+msgid "HOME=%s\n"
+msgstr ""
+
+#: src/useradd.c:430
+#, c-format
+msgid "INACTIVE=%ld\n"
+msgstr ""
+
+#: src/useradd.c:431
+#, c-format
+msgid "EXPIRE=%s\n"
+msgstr ""
+
+#: src/useradd.c:433
+#, c-format
+msgid "SHELL=%s\n"
+msgstr ""
+
+#: src/useradd.c:434
+#, c-format
+msgid "SKEL=%s\n"
+msgstr ""
+
+#: src/useradd.c:470
+#, c-format
+msgid "%s: cannot create new defaults file\n"
+msgstr ""
+
+#: src/useradd.c:564 src/useradd.c:575
+#, c-format
+msgid "%s: rename: %s"
+msgstr ""
+
+#: src/useradd.c:662 src/usermod.c:274
+#, c-format
+msgid "%s: group `%s' is a NIS group.\n"
+msgstr ""
+
+#: src/useradd.c:670 src/usermod.c:282
+#, c-format
+msgid "%s: too many groups specified (max %d).\n"
+msgstr ""
+
+#: src/useradd.c:702 src/usermod.c:314
+#, c-format
+msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"
+msgstr ""
+
+#: src/useradd.c:705
+msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n"
+msgstr ""
+
+#: src/useradd.c:708 src/usermod.c:320
+msgid "[-f inactive] [-e expire ] "
+msgstr ""
+
+#: src/useradd.c:711
+msgid "[-A program] "
+msgstr ""
+
+#: src/useradd.c:713
+msgid "[-p passwd] name\n"
+msgstr ""
+
+#: src/useradd.c:715
+#, c-format
+msgid " %s\t-D [-g group] [-b base] [-s shell]\n"
+msgstr ""
+
+#: src/useradd.c:718
+msgid "\t\t[-f inactive] [-e expire ]\n"
+msgstr ""
+
+#: src/useradd.c:815 src/usermod.c:472
+#, c-format
+msgid "%s: error locking group file\n"
+msgstr ""
+
+#: src/useradd.c:819 src/usermod.c:477
+#, c-format
+msgid "%s: error opening group file\n"
+msgstr ""
+
+#: src/useradd.c:824 src/usermod.c:584
+#, c-format
+msgid "%s: error locking shadow group file\n"
+msgstr ""
+
+#: src/useradd.c:829 src/usermod.c:590
+#, c-format
+msgid "%s: error opening shadow group file\n"
+msgstr ""
+
+#: src/useradd.c:1001
+#, c-format
+msgid "%s: uid %d is not unique\n"
+msgstr ""
+
+#: src/useradd.c:1031
+#, c-format
+msgid "%s: can't get unique uid\n"
+msgstr ""
+
+#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057
+#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157
+#, c-format
+msgid "%s: invalid field `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1153
+#, c-format
+msgid "%s: invalid base directory `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1163
+#, c-format
+msgid "%s: invalid comment `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1173
+#, c-format
+msgid "%s: invalid home directory `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1191 src/usermod.c:1080
+#, c-format
+msgid "%s: invalid date `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1203
+#, c-format
+msgid "%s: shadow passwords required for -e\n"
+msgstr ""
+
+#: src/useradd.c:1218
+#, c-format
+msgid "%s: shadow passwords required for -f\n"
+msgstr ""
+
+#: src/useradd.c:1292
+#, c-format
+msgid "%s: invalid shell `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1333
+#, c-format
+msgid "%s: invalid user name `%s'\n"
+msgstr ""
+
+#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225
+#, c-format
+msgid "%s: cannot rewrite password file\n"
+msgstr ""
+
+#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230
+#, c-format
+msgid "%s: cannot rewrite shadow password file\n"
+msgstr ""
+
+#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265
+#, c-format
+msgid "%s: unable to lock password file\n"
+msgstr ""
+
+#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269
+#, c-format
+msgid "%s: unable to open password file\n"
+msgstr ""
+
+#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274
+#, c-format
+msgid "%s: cannot lock shadow password file\n"
+msgstr ""
+
+#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279
+#, c-format
+msgid "%s: cannot open shadow password file\n"
+msgstr ""
+
+#: src/useradd.c:1529 src/usermod.c:1366
+#, c-format
+msgid "%s: error adding authentication method\n"
+msgstr ""
+
+#: src/useradd.c:1552
+#, c-format
+msgid "%s: error adding new password entry\n"
+msgstr ""
+
+#: src/useradd.c:1567
+#, c-format
+msgid "%s: error updating password dbm entry\n"
+msgstr ""
+
+#: src/useradd.c:1583 src/usermod.c:1425
+#, c-format
+msgid "%s: error adding new shadow password entry\n"
+msgstr ""
+
+#: src/useradd.c:1599 src/usermod.c:1440
+#, c-format
+msgid "%s: error updating shadow passwd dbm entry\n"
+msgstr ""
+
+#: src/useradd.c:1631
+#, c-format
+msgid "%s: cannot create directory %s\n"
+msgstr ""
+
+#: src/useradd.c:1708 src/usermod.c:1203
+#, c-format
+msgid "%s: user %s exists\n"
+msgstr ""
+
+#: src/useradd.c:1738
+#, c-format
+msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n"
+msgstr ""
+
+#: src/userdel.c:127
+#, c-format
+msgid "usage: %s [-r] name\n"
+msgstr ""
+
+#: src/userdel.c:178 src/userdel.c:260
+#, c-format
+msgid "%s: error updating group entry\n"
+msgstr ""
+
+#: src/userdel.c:188 src/userdel.c:269
+#, c-format
+msgid "%s: cannot update dbm group entry\n"
+msgstr ""
+
+#: src/userdel.c:215
+#, c-format
+msgid "%s: cannot remove dbm group entry\n"
+msgstr ""
+
+#: src/userdel.c:300
+#, c-format
+msgid "%s: cannot rewrite TCFS key file\n"
+msgstr ""
+
+#: src/userdel.c:380
+#, c-format
+msgid "%s: cannot lock TCFS key file\n"
+msgstr ""
+
+#: src/userdel.c:384
+#, c-format
+msgid "%s: cannot open TCFS key file\n"
+msgstr ""
+
+#: src/userdel.c:393
+#, c-format
+msgid "%s: cannot open group file\n"
+msgstr ""
+
+#: src/userdel.c:403
+#, c-format
+msgid "%s: cannot open shadow group file\n"
+msgstr ""
+
+#: src/userdel.c:434 src/userdel.c:449
+#, c-format
+msgid "%s: error deleting authentication\n"
+msgstr ""
+
+#: src/userdel.c:458
+#, c-format
+msgid "%s: error deleting password entry\n"
+msgstr ""
+
+#: src/userdel.c:461
+#, c-format
+msgid "%s: error deleting shadow password entry\n"
+msgstr ""
+
+#: src/userdel.c:470
+#, c-format
+msgid "%s: error deleting TCFS entry\n"
+msgstr ""
+
+#: src/userdel.c:483
+#, c-format
+msgid "%s: error deleting password dbm entry\n"
+msgstr ""
+
+#: src/userdel.c:502
+#, c-format
+msgid "%s: error deleting shadow passwd dbm entry\n"
+msgstr ""
+
+#: src/userdel.c:543
+#, c-format
+msgid "%s: user %s is currently logged in\n"
+msgstr ""
+
+#: src/userdel.c:660
+#, c-format
+msgid "%s: warning: %s not owned by %s, not removing\n"
+msgstr ""
+
+#: src/userdel.c:666
+#, c-format
+msgid "%s: warning: can't remove "
+msgstr ""
+
+#: src/userdel.c:741 src/usermod.c:994
+#, c-format
+msgid "%s: user %s does not exist\n"
+msgstr ""
+
+#: src/userdel.c:755 src/usermod.c:1010
+#, c-format
+msgid "%s: user %s is a NIS user\n"
+msgstr ""
+
+#: src/userdel.c:792
+#, c-format
+msgid "%s: %s not owned by %s, not removing\n"
+msgstr ""
+
+#: src/userdel.c:815
+#, c-format
+msgid "%s: not removing directory %s (would remove home of user %s)\n"
+msgstr ""
+
+#: src/userdel.c:828
+#, c-format
+msgid "%s: error removing directory %s\n"
+msgstr ""
+
+#: src/usermod.c:317
+msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"
+msgstr ""
+
+#: src/usermod.c:323
+msgid "[-A {DEFAULT|program},... ] "
+msgstr ""
+
+#: src/usermod.c:325
+msgid "[-p passwd] [-L|-U] name\n"
+msgstr ""
+
+#: src/usermod.c:504
+#, c-format
+msgid "%s: out of memory in update_group\n"
+msgstr ""
+
+#: src/usermod.c:627
+#, c-format
+msgid "%s: out of memory in update_gshadow\n"
+msgstr ""
+
+#: src/usermod.c:1180
+#, c-format
+msgid "%s: no flags given\n"
+msgstr ""
+
+#: src/usermod.c:1187
+#, c-format
+msgid "%s: shadow passwords required for -e and -f\n"
+msgstr ""
+
+#: src/usermod.c:1208
+#, c-format
+msgid "%s: uid %ld is not unique\n"
+msgstr ""
+
+#: src/usermod.c:1356
+#, c-format
+msgid "%s: error deleting authentication method\n"
+msgstr ""
+
+#: src/usermod.c:1376
+#, c-format
+msgid "%s: error changing authentication method\n"
+msgstr ""
+
+#: src/usermod.c:1393
+#, c-format
+msgid "%s: error changing password entry\n"
+msgstr ""
+
+#: src/usermod.c:1399
+#, c-format
+msgid "%s: error removing password entry\n"
+msgstr ""
+
+#: src/usermod.c:1407
+#, c-format
+msgid "%s: error adding password dbm entry\n"
+msgstr ""
+
+#: src/usermod.c:1414
+#, c-format
+msgid "%s: error removing passwd dbm entry\n"
+msgstr ""
+
+#: src/usermod.c:1431
+#, c-format
+msgid "%s: error removing shadow password entry\n"
+msgstr ""
+
+#: src/usermod.c:1446
+#, c-format
+msgid "%s: error removing shadow passwd dbm entry\n"
+msgstr ""
+
+#: src/usermod.c:1477
+#, c-format
+msgid "%s: directory %s exists\n"
+msgstr ""
+
+#: src/usermod.c:1484
+#, c-format
+msgid "%s: can't create %s\n"
+msgstr ""
+
+#: src/usermod.c:1490
+#, c-format
+msgid "%s: can't chown %s\n"
+msgstr ""
+
+#: src/usermod.c:1506
+#, c-format
+msgid "%s: cannot rename directory %s to %s\n"
+msgstr ""
+
+#. better leave it alone
+#: src/usermod.c:1603
+#, c-format
+msgid "%s: warning: %s not owned by %s\n"
+msgstr ""
+
+#: src/usermod.c:1609
+msgid "failed to change mailbox owner"
+msgstr ""
+
+#: src/usermod.c:1616
+msgid "failed to rename mailbox"
+msgstr ""
+
+#: src/vipw.c:102
+#, c-format
+msgid ""
+"\n"
+"%s: %s is unchanged\n"
+msgstr ""
+
+#: src/vipw.c:127
+msgid "Couldn't lock file"
+msgstr ""
+
+#: src/vipw.c:134
+msgid "Couldn't make backup"
+msgstr ""
+
+#: src/vipw.c:187
+#, c-format
+msgid "%s: can't restore %s: %s (your changes are in %s)\n"
+msgstr ""
+
+#: src/vipw.c:226
+msgid ""
+"Usage:\n"
+"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n"
+"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n"
+msgstr ""
diff --git a/current/po/stamp-cat-id b/current/po/stamp-cat-id
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/current/po/stamp-cat-id
@@ -0,0 +1 @@
+timestamp
diff --git a/current/po/sv.gmo b/current/po/sv.gmo
new file mode 100644
index 00000000..cc42273e
--- /dev/null
+++ b/current/po/sv.gmo
Binary files differ
diff --git a/current/po/sv.po b/current/po/sv.po
new file mode 100644
index 00000000..2409210d
--- /dev/null
+++ b/current/po/sv.po
@@ -0,0 +1,2406 @@
+# Swedish messages for Shadow
+# Copyright (C) 1999 Free Software Foundation, Inc.
+# Kristoffer Brånemyr <ztion@swipnet.se>, 1999.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: shadow 19990709\n"
+"POT-Creation-Date: 2000-09-02 20:40+0200\n"
+"PO-Revision-Date: 1999-08-16 21:20+0100\n"
+"Last-Translator: Kristoffer Brånemyr <ztion@swipnet.se>\n"
+"Language-Team: sv <sv@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmisc/addgrps.c:60
+#, c-format
+msgid "Warning: unknown group %s\n"
+msgstr "Varning: okänd grupp %s\n"
+
+#: libmisc/addgrps.c:71
+msgid "Warning: too many groups\n"
+msgstr "Varning: för många grupper\n"
+
+#: libmisc/age.c:104
+msgid "Your password has expired."
+msgstr "Ditt lösenord har upphört"
+
+#: libmisc/age.c:107
+msgid "Your password is inactive."
+msgstr "Ditt lösenord är inaktivt"
+
+#: libmisc/age.c:110
+msgid "Your login has expired."
+msgstr "Din användare har upphört."
+
+#: libmisc/age.c:127
+msgid " Contact the system administrator.\n"
+msgstr " Kontakta systemoperatören.\n"
+
+#: libmisc/age.c:130
+msgid " Choose a new password.\n"
+msgstr " Välj ett nytt lösenord.\n"
+
+#: libmisc/age.c:228
+#, c-format
+msgid "Your password will expire in %ld days.\n"
+msgstr "Ditt lösenord upphör om %ld dagar.\n"
+
+#: libmisc/age.c:230
+msgid "Your password will expire tomorrow.\n"
+msgstr "Ditt lösenord upphör imorgon.\n"
+
+#: libmisc/age.c:232
+msgid "Your password will expire today.\n"
+msgstr "Ditt lösenord upphör idag.\n"
+
+#: libmisc/chowntty.c:110
+#, c-format
+msgid "Unable to change tty %s"
+msgstr "Kunde inte byta tty %s"
+
+#: libmisc/env.c:160
+msgid "Environment overflow\n"
+msgstr "Miljön överflödades\n"
+
+#: libmisc/env.c:200
+#, c-format
+msgid "You may not change $%s\n"
+msgstr "Du får inte ändra $%s\n"
+
+#: libmisc/failure.c:238
+#, c-format
+msgid "%d %s since last login. Last was %s on %s.\n"
+msgstr "%d %s sedan förra inloggningen. Den sista var %s på %s.\n"
+
+#: libmisc/failure.c:239
+msgid "failures"
+msgstr "felaktiga inloggningar"
+
+#: libmisc/failure.c:239
+msgid "failure"
+msgstr "felaktig inloggning"
+
+#: libmisc/limits.c:397
+msgid "Too many logins.\n"
+msgstr "För många inloggningar.\n"
+
+#: libmisc/login_desrpc.c:63
+#, c-format
+msgid "Password does not decrypt secret key for %s.\n"
+msgstr "Lösenordet avkrypterar inte den hemliga nyckeln för %s.\n"
+
+#: libmisc/login_desrpc.c:69
+#, c-format
+msgid "Could not set %s's secret key: is the keyserv daemon running?\n"
+msgstr ""
+"Kunde inte sätta den hemliga nyckeln för %s: är keyserv demonen igång?\n"
+
+#: libmisc/mail.c:62 libmisc/mail.c:77
+msgid "You have new mail."
+msgstr "Du har ny post."
+
+#: libmisc/mail.c:73
+msgid "No mail."
+msgstr "Ingen post."
+
+#: libmisc/mail.c:75
+msgid "You have mail."
+msgstr "Du har post."
+
+#: libmisc/obscure.c:281 src/passwd.c:309
+#, c-format
+msgid "Bad password: %s. "
+msgstr "Felaktigt lösenord: %s. "
+
+#: libmisc/pam_pass.c:42
+#, c-format
+msgid "passwd: pam_start() failed, error %d\n"
+msgstr "passwd: pam_start() misslyckades, fel %d\n"
+
+#: libmisc/pam_pass.c:49
+#, c-format
+msgid "passwd: %s\n"
+msgstr "passwd: %s\n"
+
+#: libmisc/setupenv.c:205
+#, c-format
+msgid "Unable to cd to \"%s\"\n"
+msgstr "Kunde inte byta aktuell katalog till \"%s\"\n"
+
+#: libmisc/setupenv.c:213
+msgid "No directory, logging in with HOME=/"
+msgstr "Ingen hemkatalog, loggar in med HOME=/"
+
+#: libmisc/shell.c:78
+#, c-format
+msgid "Executing shell %s\n"
+msgstr "Startar skal %s\n"
+
+#.
+#. * Obviously something is really wrong - I can't figure out
+#. * how to execute this stupid shell, so I might as well give
+#. * up in disgust ...
+#.
+#: libmisc/shell.c:122
+#, c-format
+msgid "Cannot execute %s"
+msgstr "Kan inte starta %s"
+
+#: libmisc/suauth.c:99
+msgid "Access to su to that account DENIED.\n"
+msgstr "Du har inte behörighet att köra su till det kontot.\n"
+
+#: libmisc/suauth.c:106
+msgid "Password authentication bypassed.\n"
+msgstr "Hoppade över lösenordskontroll.\n"
+
+#: libmisc/suauth.c:113
+msgid "Please enter your OWN password as authentication.\n"
+msgstr "Var god skriv in ditt EGET lösenord som äkthetsbevis.\n"
+
+#: libmisc/sub.c:61
+#, c-format
+msgid "Invalid root directory \"%s\"\n"
+msgstr "Felaktig rotkatalog \"%s\"\n"
+
+#: libmisc/sub.c:73
+#, c-format
+msgid "Can't change root directory to \"%s\"\n"
+msgstr "Kan inte byta rotkatalog till \"%s\"\n"
+
+#: libmisc/xmalloc.c:28
+#, c-format
+msgid "malloc(%d) failed\n"
+msgstr "malloc(%d) misslyckades\n"
+
+#: lib/dialchk.c:71
+msgid "Dialup Password: "
+msgstr "Uppringningslösenord: "
+
+#: lib/getdef.c:253
+msgid "Could not allocate space for config info.\n"
+msgstr "Kunde inte allokera rum för konfigureringsinformation.\n"
+
+#.
+#. * Item was never found.
+#.
+#: lib/getdef.c:307
+#, c-format
+msgid "configuration error - unknown item '%s' (notify administrator)\n"
+msgstr "konfigurerings fel - okänt object \"%s\" (meddela systemoperatören)\n"
+
+#: lib/getdef.c:394
+#, c-format
+msgid "error - lookup '%s' failed\n"
+msgstr "fel - kunde inte hitta \"%s\"\n"
+
+#: lib/getdef.c:402
+#, c-format
+msgid "%s not found\n"
+msgstr "%s hittades inte\n"
+
+#.
+#. * get the password from her, and set the salt for
+#. * the decryption from the group file.
+#.
+#: lib/pwauth.c:54 src/newgrp.c:305
+msgid "Password: "
+msgstr "Lösenord: "
+
+#: lib/pwauth.c:56
+#, c-format
+msgid "%s's Password: "
+msgstr "Lösenord för %s: "
+
+#: lib/pwauth.c:270
+msgid "(Echo on) "
+msgstr ""
+
+#: lib/strerror.c:20
+#, c-format
+msgid "Unknown error %d"
+msgstr "Okänt fel %d"
+
+#: src/chage.c:156
+#, c-format
+msgid ""
+"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n"
+" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"
+msgstr ""
+"Användning: %s [ -l ] [ -m min_dagar ] [ -M max_dagar ] [ -W varna ]\n"
+" [ -I inaktiv ] [ -E utgång ] [ -d senaste_dag ] användare\n"
+
+#: src/chage.c:158
+#, c-format
+msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"
+msgstr ""
+"Användning: %s [ -l ] [ -m min_dagar ] [ -M max_dagar ] [ -d senaste_dag ] "
+"användare\n"
+
+#: src/chage.c:193
+msgid ""
+"Enter the new value, or press return for the default\n"
+"\n"
+msgstr ""
+"Skriv in det nya värdet, eller tryck på return för standardvärdet\n"
+"\n"
+
+#: src/chage.c:196
+msgid "Minimum Password Age"
+msgstr "Minsta lösenordsålder"
+
+#: src/chage.c:201
+msgid "Maximum Password Age"
+msgstr "Högsta lösenordsålder"
+
+#: src/chage.c:207
+msgid "Last Password Change (YYYY-MM-DD)"
+msgstr "Senaste lösenordsändring (ÅÅÅÅ-MM-DD)"
+
+#: src/chage.c:216
+msgid "Password Expiration Warning"
+msgstr "Lösenords upphörningsvarning"
+
+#: src/chage.c:221
+msgid "Password Inactive"
+msgstr "Lösenord inaktivt"
+
+#: src/chage.c:227
+msgid "Account Expiration Date (YYYY-MM-DD)"
+msgstr "Kontot upphör (ÅÅÅÅ-MM-DD)"
+
+#.
+#. * Start with the easy numbers - the number of days before the
+#. * password can be changed, the number of days after which the
+#. * password must be chaged, the number of days before the
+#. * password expires that the user is told, and the number of
+#. * days after the password expires that the account becomes
+#. * unusable.
+#.
+#: src/chage.c:281
+#, c-format
+msgid "Minimum:\t%ld\n"
+msgstr "Minst:\t%ld\n"
+
+#: src/chage.c:282
+#, c-format
+msgid "Maximum:\t%ld\n"
+msgstr "Högst:\t%ld\n"
+
+#: src/chage.c:284
+#, c-format
+msgid "Warning:\t%ld\n"
+msgstr "Varning:\t%ld\n"
+
+#: src/chage.c:285
+#, c-format
+msgid "Inactive:\t%ld\n"
+msgstr "Inaktivt:\t%ld\n"
+
+#.
+#. * The "last change" date is either "Never" or the date the
+#. * password was last modified. The date is the number of
+#. * days since 1/1/1970.
+#.
+#: src/chage.c:294
+msgid "Last Change:\t\t"
+msgstr "Senaste ändring:\t\t"
+
+#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340
+msgid "Never\n"
+msgstr "Aldrig\n"
+
+#.
+#. * The password expiration date is determined from the last
+#. * change date plus the number of days the password is valid
+#. * for.
+#.
+#: src/chage.c:308
+msgid "Password Expires:\t"
+msgstr "Lösenordet upphör:\t"
+
+#.
+#. * The account becomes inactive if the password is expired
+#. * for more than "inactdays". The expiration date is calculated
+#. * and the number of inactive days is added. The resulting date
+#. * is when the active will be disabled.
+#.
+#: src/chage.c:324
+#, fuzzy
+msgid "Password Inactive:\t"
+msgstr "Lösenord inaktivt"
+
+#.
+#. * The account will expire on the given date regardless of the
+#. * password expiring or not.
+#.
+#: src/chage.c:338
+#, fuzzy
+msgid "Account Expires:\t"
+msgstr "Lösenordet upphör:\t"
+
+#: src/chage.c:486
+#, c-format
+msgid "%s: do not include \"l\" with other flags\n"
+msgstr "%s: inkludera inte \"l\" tillsammands med andra flaggor\n"
+
+#: src/chage.c:498 src/chage.c:610 src/login.c:529
+#, c-format
+msgid "%s: permission denied\n"
+msgstr "%s: tillåtelse nekas\n"
+
+#: src/chage.c:510 src/chpasswd.c:120
+#, c-format
+msgid "%s: can't lock password file\n"
+msgstr "%s: kan inte låsa lösenordsfilen\n"
+
+#: src/chage.c:516 src/chpasswd.c:124
+#, c-format
+msgid "%s: can't open password file\n"
+msgstr "%s: kan inte öppna lösenordsfilen\n"
+
+#: src/chage.c:523
+#, c-format
+msgid "%s: unknown user: %s\n"
+msgstr "%s: okänd användare: %s\n"
+
+#: src/chage.c:542
+#, c-format
+msgid "%s: can't lock shadow password file\n"
+msgstr "%s: kan inte låsa skugglösenordsfilen\n"
+
+#: src/chage.c:549
+#, c-format
+msgid "%s: can't open shadow password file\n"
+msgstr "%s: kan inte öppna skugglösenordsfilen\n"
+
+#: src/chage.c:631
+#, c-format
+msgid "Changing the aging information for %s\n"
+msgstr "Ändrar åldringsinformation för %s\n"
+
+#: src/chage.c:633
+#, c-format
+msgid "%s: error changing fields\n"
+msgstr "%s: fel uppstod under byte av fält\n"
+
+#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183
+#, c-format
+msgid "%s: can't update password file\n"
+msgstr "%s: kan inte uppdatera lösenordsfilen\n"
+
+#: src/chage.c:690 src/pwunconv.c:178
+#, c-format
+msgid "%s: can't update shadow password file\n"
+msgstr "%s: kan inte uppdatera skugglösenordsfilen\n"
+
+#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409
+#: src/passwd.c:825 src/passwd.c:926
+msgid "Error updating the DBM password entry.\n"
+msgstr "Fel under uppdatering av DBM-lösenordsnoteringen.\n"
+
+#: src/chage.c:771
+#, c-format
+msgid "%s: can't rewrite shadow password file\n"
+msgstr "%s: kan inte skriva om skugglösenordsfilen\n"
+
+#: src/chage.c:785
+#, c-format
+msgid "%s: can't rewrite password file\n"
+msgstr "%s: kan inte skriva om lösenordsfilen\n"
+
+#: src/chage.c:836
+#, c-format
+msgid "%s: no aging information present\n"
+msgstr "%s: ingen åldringsinformation finns tillgänglig\n"
+
+#: src/chfn.c:107
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n"
+"\t[ -h home_ph ] [ -o other ] [ user ]\n"
+msgstr ""
+"%s [ -f hela_namnet ] [ -r rumsnummer ] [ -w arbetstele ]\n"
+"\t[ -h hemtele ] [ -o övrigt ] [ användare ]\n"
+
+#: src/chfn.c:111
+#, c-format
+msgid ""
+"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"
+msgstr ""
+"Användning: %s [ -f hela_namnet ] [ -r rumsnummer ] [ -w arbetstele ] [ -h "
+"hemtele ]\n"
+
+#: src/chfn.c:163 src/chsh.c:119
+msgid "Enter the new value, or press return for the default\n"
+msgstr "Skriv in det nya värdet, eller tryck return för standardvärdet\n"
+
+#: src/chfn.c:166
+msgid "Full Name"
+msgstr "Hela namnet"
+
+#: src/chfn.c:168
+#, c-format
+msgid "\tFull Name: %s\n"
+msgstr "\tHela namnet: %s\n"
+
+#: src/chfn.c:171
+msgid "Room Number"
+msgstr "Rumsnummer"
+
+#: src/chfn.c:173
+#, c-format
+msgid "\tRoom Number: %s\n"
+msgstr "\tRumsnummer: %s\n"
+
+#: src/chfn.c:176
+msgid "Work Phone"
+msgstr "Arbetstelefonnummer"
+
+#: src/chfn.c:178
+#, c-format
+msgid "\tWork Phone: %s\n"
+msgstr "\tArbetstelefonnummer: %s\n"
+
+#: src/chfn.c:181
+msgid "Home Phone"
+msgstr "Hemtelefonnummer"
+
+#: src/chfn.c:183
+#, c-format
+msgid "\tHome Phone: %s\n"
+msgstr "\tHemtelefonnummer: %s\n"
+
+#: src/chfn.c:186
+msgid "Other"
+msgstr "Övrigt"
+
+#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330
+#: src/chfn.c:391 src/passwd.c:1226
+#, c-format
+msgid "%s: Permission denied.\n"
+msgstr "%s: Tillåtelse nekas.\n"
+
+#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277
+#, c-format
+msgid "%s: Unknown user %s\n"
+msgstr "%s: Okänd användare %s\n"
+
+#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207
+#, c-format
+msgid "%s: Cannot determine your user name.\n"
+msgstr "%s: Kan inte avgöra ditt användarnamn.\n"
+
+#: src/chfn.c:373 src/chsh.c:250
+#, c-format
+msgid "%s: cannot change user `%s' on NIS client.\n"
+msgstr "%s: kan inte ändra användare \"%s\" på NIS-klienten.\n"
+
+#: src/chfn.c:378 src/chsh.c:257
+#, c-format
+msgid "%s: `%s' is the NIS master for this client.\n"
+msgstr "%s: \"%s\" är NIS-mästare för denna klient.\n"
+
+#: src/chfn.c:453
+#, c-format
+msgid "Changing the user information for %s\n"
+msgstr "Ändrar användarinformation för %s\n"
+
+#: src/chfn.c:462
+#, c-format
+msgid "%s: invalid name: \"%s\"\n"
+msgstr "%s: felaktigt namn: \"%s\"\n"
+
+#: src/chfn.c:467
+#, c-format
+msgid "%s: invalid room number: \"%s\"\n"
+msgstr "%s: felaktigt rumsnummer: \"%s\"\n"
+
+#: src/chfn.c:472
+#, c-format
+msgid "%s: invalid work phone: \"%s\"\n"
+msgstr "%s: felaktigt arbetstelefonnummer: \"%s\"\n"
+
+#: src/chfn.c:477
+#, c-format
+msgid "%s: invalid home phone: \"%s\"\n"
+msgstr "%s: felaktigt hemtelefonnummer: \"%s\"\n"
+
+#: src/chfn.c:482
+#, c-format
+msgid "%s: \"%s\" contains illegal characters\n"
+msgstr "%s: \"%s\" innehåller otillåtna tecken\n"
+
+#: src/chfn.c:494
+#, c-format
+msgid "%s: fields too long\n"
+msgstr "%s: för långa fält\n"
+
+#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388
+msgid "Cannot change ID to root.\n"
+msgstr "Kan inte ändra ID till root.\n"
+
+#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880
+msgid "Cannot lock the password file; try again later.\n"
+msgstr "Kan inte låsa lösenordsfilen; försök igen senare.\n"
+
+#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885
+msgid "Cannot open the password file.\n"
+msgstr "Kan inte öppna lösenordsfilen.\n"
+
+#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313
+#, c-format
+msgid "%s: %s not found in /etc/passwd\n"
+msgstr "%s: %s hittades inte i /etc/passwd\n"
+
+#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920
+#: src/passwd.c:960
+msgid "Error updating the password entry.\n"
+msgstr "Fel under uppdatering av lösenordsnoteringen.\n"
+
+#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933
+msgid "Cannot commit password file changes.\n"
+msgstr "Kan inte genomföra ändringar i lösenordsfilen.\n"
+
+#: src/chfn.c:592 src/chsh.c:431
+msgid "Cannot unlock the password file.\n"
+msgstr "Kan inte låsa upp lösenordsfilen.\n"
+
+#: src/chpasswd.c:76
+#, c-format
+msgid "usage: %s [-e]\n"
+msgstr "Användning: %s [-e]\n"
+
+#: src/chpasswd.c:132 src/pwconv.c:104
+#, c-format
+msgid "%s: can't lock shadow file\n"
+msgstr "%s: kan inte låsa skuggfilen\n"
+
+#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118
+#: src/pwunconv.c:123
+#, c-format
+msgid "%s: can't open shadow file\n"
+msgstr "%s: kan inte öppna skuggfilen\n"
+
+#: src/chpasswd.c:159 src/newusers.c:415
+#, c-format
+msgid "%s: line %d: line too long\n"
+msgstr "%s: rad %d: för lång rad\n"
+
+#: src/chpasswd.c:179
+#, c-format
+msgid "%s: line %d: missing new password\n"
+msgstr "%s: rad %d: det nya lösenordet saknas\n"
+
+#: src/chpasswd.c:195
+#, c-format
+msgid "%s: line %d: unknown user %s\n"
+msgstr "%s: rad %d: okänd användare %s\n"
+
+#: src/chpasswd.c:247
+#, c-format
+msgid "%s: line %d: cannot update password entry\n"
+msgstr "%s: rad %d: kan inte uppdatera lösenordsnoteringen\n"
+
+#: src/chpasswd.c:263 src/newusers.c:535
+#, c-format
+msgid "%s: error detected, changes ignored\n"
+msgstr "%s: fel upptäcktes, ändringarna ignorerades\n"
+
+#: src/chpasswd.c:274
+#, c-format
+msgid "%s: error updating shadow file\n"
+msgstr "%s: fel under uppdatering av skuggfilen\n"
+
+#: src/chpasswd.c:282
+#, c-format
+msgid "%s: error updating password file\n"
+msgstr "%s: fel under uppdatering av lösenordsfilen\n"
+
+#: src/chsh.c:105
+#, c-format
+msgid "Usage: %s [ -s shell ] [ name ]\n"
+msgstr "Användning: %s [ -s skal ] [ namn ]\n"
+
+#: src/chsh.c:120
+msgid "Login Shell"
+msgstr "Inloggningsskal"
+
+#: src/chsh.c:273 src/chsh.c:286
+#, c-format
+msgid "You may not change the shell for %s.\n"
+msgstr "Du får inte ändra skal åt %s.\n"
+
+#: src/chsh.c:315
+#, c-format
+msgid "Changing the login shell for %s\n"
+msgstr "Ändrar inloggningsskal åt %s\n"
+
+#: src/chsh.c:327
+#, c-format
+msgid "%s: Invalid entry: %s\n"
+msgstr "%s: Felaktig notering: %s\n"
+
+#: src/chsh.c:332
+#, c-format
+msgid "%s is an invalid shell.\n"
+msgstr "%s är ett felaktigt skal.\n"
+
+#: src/dpasswd.c:69
+#, c-format
+msgid "Usage: %s [ -(a|d) ] shell\n"
+msgstr "Användning: %s [ -(a|d) ] skal\n"
+
+#: src/dpasswd.c:134
+msgid "Shell password: "
+msgstr "Skallösenord: "
+
+#: src/dpasswd.c:140
+msgid "re-enter Shell password: "
+msgstr "skriv in skallösenordet igen: "
+
+#: src/dpasswd.c:147
+#, c-format
+msgid "%s: Passwords do not match, try again.\n"
+msgstr "%s: Lösenorden matchar inte varandra, försök igen.\n"
+
+#: src/dpasswd.c:167
+#, c-format
+msgid "%s: can't create %s"
+msgstr "%s: kan inte skapa %s"
+
+#: src/dpasswd.c:172
+#, c-format
+msgid "%s: can't open %s"
+msgstr "%s: kan inte öppna %s"
+
+#: src/dpasswd.c:200
+#, c-format
+msgid "%s: Shell %s not found.\n"
+msgstr "%s: Hittade inte skalet %s.\n"
+
+#: src/expiry.c:84
+msgid "Usage: expiry { -f | -c }\n"
+msgstr "Användning: expiry { -f | -c }\n"
+
+#: src/expiry.c:137
+#, c-format
+msgid "%s: WARNING! Must be set-UID root!\n"
+msgstr "%s: VARNING! Måste vara set-UID root!\n"
+
+#: src/expiry.c:148
+#, c-format
+msgid "%s: unknown user\n"
+msgstr "%s: okänd användare\n"
+
+#: src/faillog.c:79
+#, c-format
+msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"
+msgstr ""
+"Användning: %s [-a|-u användare] [-m högst] [-r] [-t dagar] [-l låssek]\n"
+
+#: src/faillog.c:134 src/lastlog.c:94
+#, c-format
+msgid "Unknown User: %s\n"
+msgstr "Okänd användare: %s\n"
+
+#: src/faillog.c:215
+msgid "Username Failures Maximum Latest\n"
+msgstr "Användarnamn Felaktiga inloggningar Högsta Senaste\n"
+
+#: src/faillog.c:232
+#, c-format
+msgid " %s on %s"
+msgstr " %s på %s"
+
+#: src/faillog.c:236
+#, c-format
+msgid " [%lds left]"
+msgstr " [%lds kvar]"
+
+#: src/faillog.c:239
+#, c-format
+msgid " [%lds lock]"
+msgstr " [%lds låsning]"
+
+#: src/gpasswd.c:89
+#, c-format
+msgid "usage: %s [-r|-R] group\n"
+msgstr "Användning: %s [-r|-R] grupp\n"
+
+#: src/gpasswd.c:90
+#, c-format
+msgid " %s [-a user] group\n"
+msgstr " %s [-a användare] grupp\n"
+
+#: src/gpasswd.c:91
+#, c-format
+msgid " %s [-d user] group\n"
+msgstr " %s [-d användare] grupp\n"
+
+#: src/gpasswd.c:93
+#, c-format
+msgid " %s [-A user,...] [-M user,...] group\n"
+msgstr " %s [-A användare,...] [-M användare,...] grupp\n"
+
+#: src/gpasswd.c:96
+#, c-format
+msgid " %s [-M user,...] group\n"
+msgstr " %s [-M användare,...] grupp\n"
+
+#: src/gpasswd.c:160 src/gpasswd.c:245
+#, c-format
+msgid "%s: unknown user %s\n"
+msgstr "%s: okänd användare %s\n"
+
+#: src/gpasswd.c:172
+msgid "Permission denied.\n"
+msgstr "Tillåtelse nekas.\n"
+
+#: src/gpasswd.c:257
+#, c-format
+msgid "%s: shadow group passwords required for -A\n"
+msgstr "%s: skuggrupplösenord krävs för -A\n"
+
+#: src/gpasswd.c:308
+msgid "Who are you?\n"
+msgstr "Vem är du?\n"
+
+#: src/gpasswd.c:328 src/newgrp.c:251
+#, c-format
+msgid "unknown group: %s\n"
+msgstr "okänd grupp: %s\n"
+
+#: src/gpasswd.c:436
+#, c-format
+msgid "Adding user %s to group %s\n"
+msgstr "Lägger till användare %s till grupp %s\n"
+
+#: src/gpasswd.c:453
+#, c-format
+msgid "Removing user %s from group %s\n"
+msgstr "Tar bort användare %s från grupp %s\n"
+
+#: src/gpasswd.c:466
+#, c-format
+msgid "%s: unknown member %s\n"
+msgstr "%s: okänd medlem %s\n"
+
+#: src/gpasswd.c:513
+#, c-format
+msgid "%s: Not a tty\n"
+msgstr "%s: Inte en tty\n"
+
+#.
+#. * A new password is to be entered and it must be encrypted,
+#. * etc. The password will be prompted for twice, and both
+#. * entries must be identical. There is no need to validate
+#. * the old password since the invoker is either the group
+#. * owner, or root.
+#.
+#: src/gpasswd.c:535
+#, c-format
+msgid "Changing the password for group %s\n"
+msgstr "Ändrar lösenordet för grupp %s\n"
+
+#: src/gpasswd.c:538
+msgid "New Password: "
+msgstr "Nytt lösenord: "
+
+#: src/gpasswd.c:543 src/passwd.c:422
+msgid "Re-enter new password: "
+msgstr "Skriv in det nya lösenordet igen: "
+
+#: src/gpasswd.c:555
+msgid "They don't match; try again"
+msgstr "De matchar inte; försök igen"
+
+#: src/gpasswd.c:559
+#, c-format
+msgid "%s: Try again later\n"
+msgstr "%s: Försök igen senare\n"
+
+#: src/gpasswd.c:590
+#, c-format
+msgid "%s: can't get lock\n"
+msgstr "%s: kan inte låsa\n"
+
+#: src/gpasswd.c:596
+#, c-format
+msgid "%s: can't get shadow lock\n"
+msgstr "%s: kan inte låsa skuggfilen\n"
+
+#: src/gpasswd.c:602
+#, c-format
+msgid "%s: can't open file\n"
+msgstr "%s: kan inte öppna filen\n"
+
+#: src/gpasswd.c:614
+#, c-format
+msgid "%s: can't update entry\n"
+msgstr "%s: kan inte uppdatera noteringen\n"
+
+#: src/gpasswd.c:620
+#, c-format
+msgid "%s: can't update shadow entry\n"
+msgstr "%s: kan inte uppdatera noteringen i skuggfilen\n"
+
+#: src/gpasswd.c:626
+#, c-format
+msgid "%s: can't re-write file\n"
+msgstr "%s: kan inte skriva om filen\n"
+
+#: src/gpasswd.c:632
+#, c-format
+msgid "%s: can't re-write shadow file\n"
+msgstr "%s: kan inte skriva om skuggfilen\n"
+
+#: src/gpasswd.c:640
+#, c-format
+msgid "%s: can't unlock file\n"
+msgstr "%s: kan inte låsa upp filen\n"
+
+#: src/gpasswd.c:645
+#, c-format
+msgid "%s: can't update DBM files\n"
+msgstr "%s: kan inte uppdatera DBM-filer\n"
+
+#: src/gpasswd.c:652
+#, c-format
+msgid "%s: can't update DBM shadow files\n"
+msgstr "%s: kan inte uppdatera DBM-skuggfiler\n"
+
+#: src/groupadd.c:105
+msgid "usage: groupadd [-g gid [-o]] group\n"
+msgstr "Användning: groupadd [-g gid [-o]] grupp\n"
+
+#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230
+#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675
+#, c-format
+msgid "%s: error adding new group entry\n"
+msgstr "%s: gick inte att lägga till en ny gruppnotering\n"
+
+#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942
+#: src/usermod.c:551 src/usermod.c:687
+#, c-format
+msgid "%s: cannot add new dbm group entry\n"
+msgstr "%s: kan inte lägga till en ny dbm-gruppnotering\n"
+
+#: src/groupadd.c:258 src/useradd.c:996
+#, c-format
+msgid "%s: name %s is not unique\n"
+msgstr "%s: namnet %s är inte unikt\n"
+
+#: src/groupadd.c:273
+#, c-format
+msgid "%s: gid %ld is not unique\n"
+msgstr "%s: gid %ld är inte unikt\n"
+
+#: src/groupadd.c:297
+#, c-format
+msgid "%s: can't get unique gid\n"
+msgstr "%s: kan inte hitta ett unikt gid\n"
+
+#.
+#. * All invalid group names land here.
+#.
+#: src/groupadd.c:321 src/groupmod.c:341
+#, c-format
+msgid "%s: %s is a not a valid group name\n"
+msgstr "%s: %s är inte ett giltigt gruppnamn\n"
+
+#: src/groupadd.c:350 src/groupmod.c:367
+#, c-format
+msgid "%s: invalid group %s\n"
+msgstr "%s: ogiltig grupp %s\n"
+
+#: src/groupadd.c:367 src/useradd.c:1272
+#, c-format
+msgid "%s: -O requires NAME=VALUE\n"
+msgstr "%s: -O kräver NAME=VÄRDE\n"
+
+#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381
+#: src/userdel.c:303 src/usermod.c:563
+#, c-format
+msgid "%s: cannot rewrite group file\n"
+msgstr "%s: kan inte skriva om gruppfilen\n"
+
+#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389
+#: src/userdel.c:309 src/usermod.c:700
+#, c-format
+msgid "%s: cannot rewrite shadow group file\n"
+msgstr "%s: kan inte skriva om skuggruppfilen\n"
+
+#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389
+#, c-format
+msgid "%s: unable to lock group file\n"
+msgstr "%s: kan inte låsa gruppfilen\n"
+
+#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432
+#, c-format
+msgid "%s: unable to open group file\n"
+msgstr "%s: kan inte öppna gruppfilen\n"
+
+#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398
+#, c-format
+msgid "%s: unable to lock shadow group file\n"
+msgstr "%s: kan inte låsa skuggruppfilen\n"
+
+#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442
+#, c-format
+msgid "%s: unable to open shadow group file\n"
+msgstr "%s: kan inte öppna skuggruppfilen\n"
+
+#: src/groupadd.c:518
+#, c-format
+msgid "%s: group %s exists\n"
+msgstr "%s: grupp %s existerar\n"
+
+#: src/groupdel.c:86
+msgid "usage: groupdel group\n"
+msgstr "Användning: groupdel grupp\n"
+
+#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234
+#, c-format
+msgid "%s: error removing group entry\n"
+msgstr "%s: fel under borttagning av gruppnotering\n"
+
+#: src/groupdel.c:116 src/groupmod.c:206
+#, c-format
+msgid "%s: error removing group dbm entry\n"
+msgstr "%s: fel under borttagning av dbm-gruppnotering\n"
+
+#: src/groupdel.c:131
+#, c-format
+msgid "%s: error removing shadow group entry\n"
+msgstr "%s: fel under borttagning av skuggruppnotering\n"
+
+#: src/groupdel.c:144 src/groupmod.c:252
+#, c-format
+msgid "%s: error removing shadow group dbm entry\n"
+msgstr "%s: fel under borttagning av dbm-skuggruppnotering\n"
+
+#.
+#. * Can't remove the group.
+#.
+#: src/groupdel.c:248
+#, c-format
+msgid "%s: cannot remove user's primary group.\n"
+msgstr "%s: kan inte ta bort användarens primära grupp.\n"
+
+#: src/groupdel.c:305 src/groupmod.c:501
+#, c-format
+msgid "%s: group %s does not exist\n"
+msgstr "%s: grupp %s existerar inte\n"
+
+#: src/groupdel.c:319 src/groupmod.c:517
+#, c-format
+msgid "%s: group %s is a NIS group\n"
+msgstr "%s: grupp %s är en NIS-grupp\n"
+
+#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016
+#, c-format
+msgid "%s: %s is the NIS master\n"
+msgstr "%s: %s är NIS-mästeren\n"
+
+#: src/groupmod.c:105
+msgid "usage: groupmod [-g gid [-o]] [-n name] group\n"
+msgstr "Användning: groupmod [-g gid [-o]] [-n namn] grupp\n"
+
+#: src/groupmod.c:165
+#, c-format
+msgid "%s: %s not found in /etc/group\n"
+msgstr "%s: %s hittades inte i /etc/group\n"
+
+#: src/groupmod.c:246
+#, c-format
+msgid "%s: cannot add new dbm shadow group entry\n"
+msgstr "%s: kunde inte lägga till en ny dbm-skuggruppnotering\n"
+
+#: src/groupmod.c:299
+#, c-format
+msgid "%s: %ld is not a unique gid\n"
+msgstr "%s: %ld är inte ett unikt gid\n"
+
+#: src/groupmod.c:330
+#, c-format
+msgid "%s: %s is not a unique name\n"
+msgstr "%s: %s är inte ett unikt namn\n"
+
+#: src/groups.c:62
+#, c-format
+msgid "unknown user %s\n"
+msgstr "okänd användare %s\n"
+
+#: src/grpck.c:98
+#, c-format
+msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n"
+msgstr "Användning: %s [ -r ] [ grupp [ gshadow ] ]\n"
+
+#: src/grpck.c:100
+#, c-format
+msgid "Usage: %s [ -r ] [ group ]\n"
+msgstr "Användning: %s [ -r ] [ grupp ]\n"
+
+#: src/grpck.c:119 src/pwck.c:119
+msgid "No"
+msgstr "Nej"
+
+#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225
+#, c-format
+msgid "%s: cannot lock file %s\n"
+msgstr "%s: kan inte låsa filen %s\n"
+
+#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241
+#: src/pwck.c:250
+#, c-format
+msgid "%s: cannot open file %s\n"
+msgstr "%s: kan inte öppna filen %s\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:298
+msgid "invalid group file entry\n"
+msgstr "felaktig gruppfilsnotering\n"
+
+#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517
+#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517
+#: src/pwck.c:541
+#, c-format
+msgid "delete line `%s'? "
+msgstr "ta bort rad \"%s\"? "
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:361
+msgid "duplicate group entry\n"
+msgstr "dubblett av gruppnotering\n"
+
+#: src/grpck.c:378
+#, c-format
+msgid "invalid group name `%s'\n"
+msgstr "ogiltigt gruppnamn \"%s\"\n"
+
+#: src/grpck.c:388
+#, c-format
+msgid "group %s: bad GID (%d)\n"
+msgstr "grupp %s: felaktigt GID (%d)\n"
+
+#: src/grpck.c:414
+#, c-format
+msgid "group %s: no user %s\n"
+msgstr "grupp %s: användaren %s finns inte\n"
+
+#: src/grpck.c:416 src/grpck.c:585
+#, c-format
+msgid "delete member `%s'? "
+msgstr "ta bort medlem \"%s\"? "
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/grpck.c:453
+msgid "invalid shadow group file entry\n"
+msgstr "felaktig skuggruppfilsnotering\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/grpck.c:516
+msgid "duplicate shadow group entry\n"
+msgstr "dubblett av skuggruppfilsnotering\n"
+
+#: src/grpck.c:533
+msgid "no matching group file entry\n"
+msgstr "inga matchande gruppfilsnoteringar\n"
+
+#: src/grpck.c:553
+#, c-format
+msgid "shadow group %s: no administrative user %s\n"
+msgstr "skuggrupp %s: finns ingen administrativ användare %s\n"
+
+#: src/grpck.c:555
+#, c-format
+msgid "delete administrative member `%s'? "
+msgstr "ta bort administrativa medlemmen \"%s\"? "
+
+#: src/grpck.c:583
+#, c-format
+msgid "shadow group %s: no user %s\n"
+msgstr "skuggrupp %s: finns ingen användare %s\n"
+
+#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580
+#, c-format
+msgid "%s: cannot update file %s\n"
+msgstr "%s: kan inte uppdatera filen %s\n"
+
+#: src/grpck.c:640 src/pwck.c:606
+#, c-format
+msgid "%s: the files have been updated; run mkpasswd\n"
+msgstr "%s: filerna är uppdaterade; kör mkpasswd\n"
+
+#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611
+#, c-format
+msgid "%s: no changes\n"
+msgstr "%s: inga ändringar\n"
+
+#: src/grpck.c:644 src/pwck.c:610
+#, c-format
+msgid "%s: the files have been updated\n"
+msgstr "%s: filerna är uppdaterade\n"
+
+#: src/grpconv.c:62 src/grpunconv.c:63
+#, c-format
+msgid "%s: can't lock group file\n"
+msgstr "%s: kan inte låsa gruppfilen\n"
+
+#: src/grpconv.c:67 src/grpunconv.c:68
+#, c-format
+msgid "%s: can't open group file\n"
+msgstr "%s: kan inte öppna gruppfilen\n"
+
+#: src/grpconv.c:72 src/grpunconv.c:73
+#, c-format
+msgid "%s: can't lock shadow group file\n"
+msgstr "%s: kan inte låsa skuggruppfilen\n"
+
+#: src/grpconv.c:77 src/grpunconv.c:78
+#, c-format
+msgid "%s: can't open shadow group file\n"
+msgstr "%s: kan inte öppna skuggruppfilen\n"
+
+#.
+#. * This shouldn't happen (the entry exists) but...
+#.
+#: src/grpconv.c:93
+#, c-format
+msgid "%s: can't remove shadow group %s\n"
+msgstr "%s: kan inte ta bort skuggruppen %s\n"
+
+#: src/grpconv.c:134 src/pwconv.c:160
+#, c-format
+msgid "%s: can't update shadow entry for %s\n"
+msgstr "%s: kan inte uppdatera skuggnoteringen för %s\n"
+
+#: src/grpconv.c:143 src/grpunconv.c:94
+#, c-format
+msgid "%s: can't update entry for group %s\n"
+msgstr "%s: kan inte uppdatera noteringen för gruppen %s\n"
+
+#: src/grpconv.c:150 src/grpunconv.c:102
+#, c-format
+msgid "%s: can't update shadow group file\n"
+msgstr "%s: kan inte uppdatera skuggruppfilen\n"
+
+#: src/grpconv.c:154 src/grpunconv.c:107
+#, c-format
+msgid "%s: can't update group file\n"
+msgstr "%s: kan inte uppdatera gruppfilen\n"
+
+#: src/grpconv.c:169 src/grpunconv.c:128
+#, c-format
+msgid "%s: not configured for shadow group support.\n"
+msgstr "%s: inte konfigurerad med stöd för skuggrupper.\n"
+
+#: src/grpunconv.c:112
+#, c-format
+msgid "%s: can't delete shadow group file\n"
+msgstr "%s: kan inte ta bort skuggruppfilen\n"
+
+#: src/id.c:56
+msgid "usage: id [ -a ]\n"
+msgstr "Användning: id [ -a ]\n"
+
+#: src/id.c:58
+msgid "usage: id\n"
+msgstr "Användning: id\n"
+
+#: src/id.c:118
+#, c-format
+msgid "uid=%d(%s)"
+msgstr "uid=%d(%s)"
+
+#: src/id.c:120
+#, c-format
+msgid "uid=%d"
+msgstr "uid=%d"
+
+#: src/id.c:124
+#, c-format
+msgid " gid=%d(%s)"
+msgstr " gid=%d(%s)"
+
+#: src/id.c:126
+#, c-format
+msgid " gid=%d"
+msgstr " gid=%d"
+
+#: src/id.c:136
+#, c-format
+msgid " euid=%d(%s)"
+msgstr " euid=%d(%s)"
+
+#: src/id.c:138
+#, c-format
+msgid " euid=%d"
+msgstr " euid=%d"
+
+#: src/id.c:143
+#, c-format
+msgid " egid=%d(%s)"
+msgstr " egid=%d(%s)"
+
+#: src/id.c:145
+#, c-format
+msgid " egid=%d"
+msgstr " egid=%d"
+
+#.
+#. * Start off the group message. It will be of the format
+#. *
+#. * groups=###(aaa),###(aaa),###(aaa)
+#. *
+#. * where "###" is a numerical value and "aaa" is the
+#. * corresponding name for each respective numerical value.
+#.
+#: src/id.c:166
+msgid " groups="
+msgstr " grupper="
+
+#: src/lastlog.c:167
+msgid "Username Port From Latest\n"
+msgstr "Användarnamn Port Från Senaste\n"
+
+#: src/lastlog.c:169
+msgid "Username Port Latest\n"
+msgstr "Användarnamn Port Senaste\n"
+
+#: src/lastlog.c:183
+msgid "**Never logged in**"
+msgstr "**Aldrig inloggad**"
+
+#: src/login.c:198
+#, c-format
+msgid "usage: %s [-p] [name]\n"
+msgstr "Användning: %s [-p] [namn]\n"
+
+#: src/login.c:201
+#, c-format
+msgid " %s [-p] [-h host] [-f name]\n"
+msgstr " %s [-p] [-h värd] [-f namn]\n"
+
+#: src/login.c:203
+#, c-format
+msgid " %s [-p] -r host\n"
+msgstr " %s [-p] -r värd\n"
+
+#: src/login.c:286
+msgid "Invalid login time\n"
+msgstr "Felaktig inloggningstid\n"
+
+#: src/login.c:341
+msgid ""
+"\n"
+"System closed for routine maintenance\n"
+msgstr ""
+"\n"
+"Systemet är stängt för rutinunderhåll\n"
+
+#: src/login.c:351
+msgid ""
+"\n"
+"[Disconnect bypassed -- root login allowed.]\n"
+msgstr ""
+"\n"
+"[Nerkoppling kringgicks -- root inloggning tillåten.]\n"
+
+#: src/login.c:390
+#, c-format
+msgid ""
+"\n"
+"Login timed out after %d seconds.\n"
+msgstr ""
+"\n"
+"Inloggningen avbröts efter %d sekunders inaktivitet.\n"
+
+#: src/login.c:692
+#, c-format
+msgid " on `%.100s' from `%.200s'"
+msgstr " på \"%.100s\" från \"%.200s\""
+
+#: src/login.c:694
+#, c-format
+msgid " on `%.100s'"
+msgstr " på \"%.100s\""
+
+#: src/login.c:834
+#, c-format
+msgid ""
+"\n"
+"%s login: "
+msgstr ""
+"\n"
+"%s användare: "
+
+#: src/login.c:836
+msgid "login: "
+msgstr "användare: "
+
+#: src/login.c:1026 src/sulogin.c:231
+msgid "Login incorrect"
+msgstr "Felaktig inloggning"
+
+#: src/login.c:1213
+msgid "Warning: login re-enabled after temporary lockout.\n"
+msgstr "Varning: inloggning på nytt aktiv efter den temporära utelåsningen.\n"
+
+#: src/login.c:1223
+#, c-format
+msgid "Last login: %s on %s"
+msgstr "Senaste inloggning: %s på %s"
+
+#: src/login.c:1226
+#, c-format
+msgid "Last login: %.19s on %s"
+msgstr "Senaste inloggning: %.19s på %s"
+
+#: src/login.c:1231
+#, c-format
+msgid " from %.*s"
+msgstr " från %.*s"
+
+#: src/login.c:1303
+msgid "Starting rad_login\n"
+msgstr "Startar rad_login\n"
+
+#: src/mkpasswd.c:49
+#, c-format
+msgid "%s: no DBM database on system - no action performed\n"
+msgstr "%s: ingen DBM-databas på systemet - ingen åtgärd genomfördes\n"
+
+#: src/mkpasswd.c:245 src/mkpasswd.c:249
+#, c-format
+msgid "%s: cannot overwrite file %s\n"
+msgstr "%s: kan inte skriva över filen %s\n"
+
+#: src/mkpasswd.c:263
+#, c-format
+msgid "%s: cannot open DBM files for %s\n"
+msgstr "%s: kan inte öppna DBM-filer för %s\n"
+
+#: src/mkpasswd.c:296
+#, c-format
+msgid "%s: the beginning with "
+msgstr "%s: början med "
+
+#: src/mkpasswd.c:321
+#, c-format
+msgid "%s: error parsing line \"%s\"\n"
+msgstr "%s: fel under analysering av rad \"%s\"\n"
+
+#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332
+msgid "adding record for name "
+msgstr "lägger till notering för namn "
+
+#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349
+#, c-format
+msgid "%s: error adding record for "
+msgstr "%s: fel under tillägg av notering för "
+
+#: src/mkpasswd.c:367
+#, c-format
+msgid "added %d entries, longest was %d\n"
+msgstr "lade till %d noteringar, den längsta var %d\n"
+
+#: src/mkpasswd.c:382
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"
+msgstr "Användning: %s [ -vf ] [ -p|g|sp|sg ] fil\n"
+
+#: src/mkpasswd.c:384
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n"
+msgstr "Användning: %s [ -vf ] [ -p|g|sp ] fil\n"
+
+#: src/mkpasswd.c:387
+#, c-format
+msgid "Usage: %s [ -vf ] [ -p|g ] file\n"
+msgstr "Användning: %s [ -vf ] [ -p|g ] fil\n"
+
+#: src/newgrp.c:66
+msgid "usage: newgrp [ - ] [ group ]\n"
+msgstr "Användning: newgrp [ - ] [ grupp ]\n"
+
+#: src/newgrp.c:68
+#, fuzzy
+msgid "usage: sg group [[-c] command ]\n"
+msgstr "Användning: sg grupp [ kommando ]\n"
+
+#: src/newgrp.c:125
+#, c-format
+msgid "unknown uid: %d\n"
+msgstr "okänt uid: %d\n"
+
+#: src/newgrp.c:201
+#, c-format
+msgid "unknown gid: %ld\n"
+msgstr "okänt gid: %ld\n"
+
+#: src/newgrp.c:245
+#, c-format
+msgid "unknown gid: %d\n"
+msgstr "okänt gid: %d\n"
+
+#: src/newgrp.c:323 src/newgrp.c:332
+msgid "Sorry.\n"
+msgstr "Tyvärr.\n"
+
+#: src/newgrp.c:364
+msgid "too many groups\n"
+msgstr "för många grupper\n"
+
+#: src/newusers.c:76
+#, c-format
+msgid "Usage: %s [ input ]\n"
+msgstr "Användning: %s [ indata ]\n"
+
+#: src/newusers.c:364
+#, c-format
+msgid "%s: can't lock /etc/passwd.\n"
+msgstr "%s: kan inte låsa /etc/passwd.\n"
+
+#: src/newusers.c:375
+#, c-format
+msgid "%s: can't lock files, try again later\n"
+msgstr "%s: kan inte låsa filerna, försök igen senare\n"
+
+#: src/newusers.c:390
+#, c-format
+msgid "%s: can't open files\n"
+msgstr "%s: kan inte öppna filerna\n"
+
+#: src/newusers.c:435
+#, c-format
+msgid "%s: line %d: invalid line\n"
+msgstr "%s: rad %d: ogiltig rad\n"
+
+#: src/newusers.c:453
+#, c-format
+msgid "%s: line %d: can't create GID\n"
+msgstr "%s: rad %d: kan inte skapa GID\n"
+
+#: src/newusers.c:469
+#, c-format
+msgid "%s: line %d: can't create UID\n"
+msgstr "%s: rad %d: kan inte skapa UID\n"
+
+#: src/newusers.c:481
+#, c-format
+msgid "%s: line %d: cannot find user %s\n"
+msgstr "%s: rad %d: kan inte hitta användaren %s\n"
+
+#: src/newusers.c:489
+#, c-format
+msgid "%s: line %d: can't update password\n"
+msgstr "%s: rad %d: kan inte uppdatera lösenordet\n"
+
+#: src/newusers.c:506
+#, c-format
+msgid "%s: line %d: mkdir failed\n"
+msgstr "%s: rad %d: mkdir misslyckades\n"
+
+#: src/newusers.c:510
+#, c-format
+msgid "%s: line %d: chown failed\n"
+msgstr "%s: rad %d: chown misslyckades\n"
+
+#: src/newusers.c:519
+#, c-format
+msgid "%s: line %d: can't update entry\n"
+msgstr "%s: rad %d: kan inte uppdatera notering\n"
+
+#: src/newusers.c:550
+#, c-format
+msgid "%s: error updating files\n"
+msgstr "%s: kunde inte uppdatera filerna\n"
+
+#: src/passwd.c:239
+#, c-format
+msgid "usage: %s [ -f | -s ] [ name ]\n"
+msgstr "Användning: %s [ -f | -s ] [ namn ]\n"
+
+#: src/passwd.c:242
+#, c-format
+msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"
+msgstr " %s [ -x högst ] [ -n minst ] [ -w varna ] [ -i inaktiv ] namn\n"
+
+#: src/passwd.c:245
+#, c-format
+msgid " %s { -l | -u | -d | -S | -e } name\n"
+msgstr " %s { -l | -u | -d | -S | -e } namn\n"
+
+#: src/passwd.c:347
+#, c-format
+msgid "User %s has a TCFS key, his old password is required.\n"
+msgstr "Användare %s har en TCFS-nyckel, hans förra lösenord krävs.\n"
+
+#: src/passwd.c:348
+msgid "You can use -t option to force the change.\n"
+msgstr "Du kan använda flaggan -t för att påtvinga ändringen.\n"
+
+#: src/passwd.c:354
+msgid "Old password: "
+msgstr "Förra lösenordet: "
+
+#: src/passwd.c:361
+#, c-format
+msgid "Incorrect password for `%s'\n"
+msgstr "Felaktigt lösenord för \"%s\"\n"
+
+#: src/passwd.c:374
+#, c-format
+msgid "Warning: user %s has a TCFS key.\n"
+msgstr "Varning: användare %s har en TCFS-nyckel.\n"
+
+#: src/passwd.c:392
+#, c-format
+msgid ""
+"Enter the new password (minimum of %d, maximum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"
+msgstr ""
+"Skriv in det nya lösenordet (minst %d, högst %d tecken)\n"
+"Var god använd en kombination av versaler, gemener och siffror.\n"
+
+#: src/passwd.c:399
+msgid "New password: "
+msgstr "Nytt lösenord: "
+
+#: src/passwd.c:409
+msgid "Try again.\n"
+msgstr "Försök igen.\n"
+
+#: src/passwd.c:418
+msgid ""
+"\n"
+"Warning: weak password (enter it again to use it anyway).\n"
+msgstr ""
+"\n"
+"Varning: svagt lösenord (skriv in det igen för att använda det ändå).\n"
+
+#: src/passwd.c:427
+msgid "They don't match; try again.\n"
+msgstr "De matchar inte; försök igen.\n"
+
+#: src/passwd.c:512 src/passwd.c:528
+#, c-format
+msgid "The password for %s cannot be changed.\n"
+msgstr "Lösenordet för %s kan inte bytas.\n"
+
+#: src/passwd.c:556
+#, c-format
+msgid "Sorry, the password for %s cannot be changed yet.\n"
+msgstr "Tyvärr, lösenordet för %s kan inte ändras än.\n"
+
+#: src/passwd.c:693
+#, c-format
+msgid "%s: out of memory\n"
+msgstr "%s: slut på minne\n"
+
+#: src/passwd.c:845
+msgid "Cannot lock the TCFS key database; try again later\n"
+msgstr "Kan inte låsa TCFS-nyckeldatabasen; försök igen senare\n"
+
+#: src/passwd.c:851
+msgid "Cannot open the TCFS key database.\n"
+msgstr "Kan inte öppna TCFS-nyckeldatabasen.\n"
+
+#: src/passwd.c:857
+msgid "Error updating the TCFS key database.\n"
+msgstr "Fel under uppdatering av TCFS-nyckeldatabasen.\n"
+
+#: src/passwd.c:862
+msgid "Cannot commit TCFS changes.\n"
+msgstr "Kan inte utföra TCFS ändringar.\n"
+
+#: src/passwd.c:1069
+#, c-format
+msgid "%s: Cannot execute %s"
+msgstr "%s: Kan inte starta %s"
+
+#: src/passwd.c:1176
+#, c-format
+msgid "%s: repository %s not supported\n"
+msgstr "%s: förvaringsplatsen %s stöds ej\n"
+
+#: src/passwd.c:1263
+#, c-format
+msgid "%s: Permission denied\n"
+msgstr "%s: Tillåtelse nekas\n"
+
+#: src/passwd.c:1287
+#, c-format
+msgid "You may not change the password for %s.\n"
+msgstr "Du får inte ändra lösenordet för %s.\n"
+
+#: src/passwd.c:1352
+#, c-format
+msgid "Changing password for %s\n"
+msgstr "Ändrar lösenord för %s\n"
+
+#: src/passwd.c:1356
+#, c-format
+msgid "The password for %s is unchanged.\n"
+msgstr "Lösenordet för %s är oförändrat.\n"
+
+#: src/passwd.c:1412
+msgid "Password changed.\n"
+msgstr "Lösenordet ändrat.\n"
+
+#: src/pwck.c:98
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"
+msgstr "Användning: %s [ -qr ] [ passwd [ shadow ] ]\n"
+
+#: src/pwck.c:100
+#, c-format
+msgid "Usage: %s [ -qr ] [ passwd ]\n"
+msgstr "Användning: %s [ -qr ] [ passwd ]\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:285
+msgid "invalid password file entry\n"
+msgstr "felaktig notering i lösenordsfilen\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:347
+msgid "duplicate password entry\n"
+msgstr "dubblett av lösenords notering\n"
+
+#: src/pwck.c:363
+#, c-format
+msgid "invalid user name `%s'\n"
+msgstr "ogiltigt användarnamn \"%s\"\n"
+
+#: src/pwck.c:373
+#, c-format
+msgid "user %s: bad UID (%d)\n"
+msgstr "användare %s: felaktigt UID (%d)\n"
+
+#.
+#. * No primary group, just give a warning
+#.
+#: src/pwck.c:388
+#, c-format
+msgid "user %s: no group %d\n"
+msgstr "användare %s: ingen grupp %d\n"
+
+#.
+#. * Home directory doesn't exist, give a warning
+#.
+#: src/pwck.c:403
+#, c-format
+msgid "user %s: directory %s does not exist\n"
+msgstr "användare %s: katalogen %s finns inte\n"
+
+#.
+#. * Login shell doesn't exist, give a warning
+#.
+#: src/pwck.c:418
+#, c-format
+msgid "user %s: program %s does not exist\n"
+msgstr "användare %s: programmet %s finns inte\n"
+
+#.
+#. * Tell the user this entire line is bogus and
+#. * ask them to delete it.
+#.
+#: src/pwck.c:454
+msgid "invalid shadow password file entry\n"
+msgstr "felaktig notering i skugglösenordsfilen\n"
+
+#.
+#. * Tell the user this entry is a duplicate of
+#. * another and ask them to delete it.
+#.
+#: src/pwck.c:516
+msgid "duplicate shadow password entry\n"
+msgstr "dubblett av notering i skugglösenordsfilen\n"
+
+#.
+#. * Tell the user this entry has no matching
+#. * /etc/passwd entry and ask them to delete it.
+#.
+#: src/pwck.c:540
+msgid "no matching password file entry\n"
+msgstr "ingen matchande notering i lösenordsfilen\n"
+
+#: src/pwck.c:557
+#, c-format
+msgid "user %s: last password change in the future\n"
+msgstr "användare %s: senaste lösenordsändring i framtiden\n"
+
+#: src/pwconv.c:94 src/pwunconv.c:108
+#, c-format
+msgid "%s: can't lock passwd file\n"
+msgstr "%s: kan inte låsa lösenordsfilen\n"
+
+#: src/pwconv.c:99 src/pwunconv.c:113
+#, c-format
+msgid "%s: can't open passwd file\n"
+msgstr "%s: kan inte öppna lösenordsfilen\n"
+
+#: src/pwconv.c:126
+#, c-format
+msgid "%s: can't remove shadow entry for %s\n"
+msgstr "%s: kan inte ta bort notering i skugglösenordsfilen för %s\n"
+
+#: src/pwconv.c:169
+#, c-format
+msgid "%s: can't update passwd entry for %s\n"
+msgstr "%s: kan inte uppdatera noteringen i lösenordsfilen för %s\n"
+
+#: src/pwconv.c:176
+#, c-format
+msgid "%s: can't update shadow file\n"
+msgstr "%s: kan inte uppdatera skuggfilen\n"
+
+#: src/pwconv.c:180
+#, c-format
+msgid "%s: can't update passwd file\n"
+msgstr "%s: kan inte uppdatera lösenordsfilen\n"
+
+#: src/pwunconv.c:62
+#, c-format
+msgid "%s: Shadow passwords are not configured.\n"
+msgstr "%s: Shadowlösenord är inte konfigurerade.\n"
+
+#: src/pwunconv.c:171
+#, c-format
+msgid "%s: can't update entry for user %s\n"
+msgstr "%s: kan inte uppdatera noteringen för användaren %s\n"
+
+#: src/pwunconv.c:188
+#, c-format
+msgid "%s: can't delete shadow password file\n"
+msgstr "%s: kan inte ta bort skugglösenordsfilen\n"
+
+#: src/su.c:140
+msgid "Sorry."
+msgstr "Tyvärr."
+
+#: src/su.c:222
+#, c-format
+msgid "%s: must be run from a terminal\n"
+msgstr "%s: måste köras från en terminal\n"
+
+#: src/su.c:311
+#, c-format
+msgid "%s: pam_start: error %d\n"
+msgstr "%s: pam_start: fel %d\n"
+
+#: src/su.c:337
+#, c-format
+msgid "Unknown id: %s\n"
+msgstr "Okänt id: %s\n"
+
+#. access denied (-1) or unexpected value
+#: src/su.c:372 src/su.c:387
+#, c-format
+msgid "You are not authorized to su %s\n"
+msgstr "Du har inte tillåtelse att köra su till %s\n"
+
+#. require own password
+#: src/su.c:383
+msgid "(Enter your own password.)"
+msgstr "(Skriv in ditt eget lösenord.)"
+
+#: src/su.c:404
+#, c-format
+msgid "%s: permission denied (shell).\n"
+msgstr "%s: tillåtelse nekas (skal).\n"
+
+#: src/su.c:428
+#, c-format
+msgid ""
+"%s: %s\n"
+"(Ignored)\n"
+msgstr ""
+"%s: %s\n"
+"(Ignorerad)\n"
+
+#: src/su.c:628
+msgid "No shell\n"
+msgstr "Inget skal\n"
+
+#. must be a password file!
+#: src/sulogin.c:136
+msgid "No password file\n"
+msgstr "Ingen lösenordsfil\n"
+
+#.
+#. * Fail secure
+#.
+#: src/sulogin.c:178
+msgid "No password entry for 'root'\n"
+msgstr "Ingen lösenordsnotering för \"root\"\n"
+
+#.
+#. * Here we prompt for the root password, or if no password is
+#. * given we just exit.
+#.
+#. get a password for root
+#: src/sulogin.c:192
+msgid ""
+"\n"
+"Type control-d to proceed with normal startup,\n"
+"(or give root password for system maintenance):"
+msgstr ""
+"\n"
+"Skriv control-d för att fortsätta med den normala uppstarten,\n"
+"(eller skriv in lösenordet för root för systemunderhåll):"
+
+#. make new environment active
+#: src/sulogin.c:241
+msgid "Entering System Maintenance Mode\n"
+msgstr "Går in i systemunderhållsläge\n"
+
+#: src/useradd.c:243
+#, c-format
+msgid "%s: rebuild the group database\n"
+msgstr "%s: bygg om gruppdatabasen\n"
+
+#: src/useradd.c:250
+#, c-format
+msgid "%s: rebuild the shadow group database\n"
+msgstr "%s: bygg om skuggruppdatabasen\n"
+
+#: src/useradd.c:287 src/usermod.c:967
+#, c-format
+msgid "%s: invalid numeric argument `%s'\n"
+msgstr "%s: ogiltigt numeriskt argument \"%s\"\n"
+
+#: src/useradd.c:343
+#, c-format
+msgid "%s: unknown gid %s\n"
+msgstr "%s: okänt gid %s\n"
+
+#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254
+#: src/usermod.c:1098
+#, c-format
+msgid "%s: unknown group %s\n"
+msgstr "%s: okänd grupp %s\n"
+
+#: src/useradd.c:418
+#, c-format
+msgid "group=%s,%ld basedir=%s skel=%s\n"
+msgstr "grupp=%s,%ld baskatalog=%s skel=%s\n"
+
+#: src/useradd.c:421
+#, c-format
+msgid "shell=%s "
+msgstr "skal=%s "
+
+#: src/useradd.c:423
+#, c-format
+msgid "inactive=%ld expire=%s"
+msgstr "inaktiv=%ld upphör=%s"
+
+#: src/useradd.c:427
+#, c-format
+msgid "GROUP=%ld\n"
+msgstr "GRUPP=%ld\n"
+
+#: src/useradd.c:428
+#, c-format
+msgid "HOME=%s\n"
+msgstr "HEM=%s\n"
+
+#: src/useradd.c:430
+#, c-format
+msgid "INACTIVE=%ld\n"
+msgstr "INAKTIV=%ld\n"
+
+#: src/useradd.c:431
+#, c-format
+msgid "EXPIRE=%s\n"
+msgstr "UPPHÖR=%s\n"
+
+#: src/useradd.c:433
+#, c-format
+msgid "SHELL=%s\n"
+msgstr "SKAL=%s\n"
+
+#: src/useradd.c:434
+#, c-format
+msgid "SKEL=%s\n"
+msgstr "SKEL=%s\n"
+
+#: src/useradd.c:470
+#, c-format
+msgid "%s: cannot create new defaults file\n"
+msgstr "%s: kan inte skapa en ny standardfil\n"
+
+#: src/useradd.c:564 src/useradd.c:575
+#, c-format
+msgid "%s: rename: %s"
+msgstr "%s: rename: %s"
+
+#: src/useradd.c:662 src/usermod.c:274
+#, c-format
+msgid "%s: group `%s' is a NIS group.\n"
+msgstr "%s: grupp \"%s\" är en NIS-grupp.\n"
+
+#: src/useradd.c:670 src/usermod.c:282
+#, c-format
+msgid "%s: too many groups specified (max %d).\n"
+msgstr "%s: för många grupper speciferade (max %d).\n"
+
+#: src/useradd.c:702 src/usermod.c:314
+#, c-format
+msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"
+msgstr "Användning: %s\t[-u uid [-o]] [-g grupp] [-G grupp,...] \n"
+
+#: src/useradd.c:705
+msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n"
+msgstr "\t\t[-d hem] [-s skal] [-c kommentar] [-m [-k mall]]\n"
+
+#: src/useradd.c:708 src/usermod.c:320
+msgid "[-f inactive] [-e expire ] "
+msgstr "[-f inaktiv] [-e upphör ] "
+
+#: src/useradd.c:711
+msgid "[-A program] "
+msgstr "[-A program] "
+
+#: src/useradd.c:713
+msgid "[-p passwd] name\n"
+msgstr "[-p passwd] namn\n"
+
+#: src/useradd.c:715
+#, c-format
+msgid " %s\t-D [-g group] [-b base] [-s shell]\n"
+msgstr " %s\t-D [-g grupp] [-b bas] [-s skal]\n"
+
+#: src/useradd.c:718
+msgid "\t\t[-f inactive] [-e expire ]\n"
+msgstr "\t\t[-f inaktiv] [-e utgång ]\n"
+
+#: src/useradd.c:815 src/usermod.c:472
+#, c-format
+msgid "%s: error locking group file\n"
+msgstr "%s: fel under låsning av gruppfilen\n"
+
+#: src/useradd.c:819 src/usermod.c:477
+#, c-format
+msgid "%s: error opening group file\n"
+msgstr "%s: fel under öppning av gruppfilen\n"
+
+#: src/useradd.c:824 src/usermod.c:584
+#, c-format
+msgid "%s: error locking shadow group file\n"
+msgstr "%s: fel under låsning av skuggruppfilen\n"
+
+#: src/useradd.c:829 src/usermod.c:590
+#, c-format
+msgid "%s: error opening shadow group file\n"
+msgstr "%s: fel under öppning av skuggruppfilen\n"
+
+#: src/useradd.c:1001
+#, c-format
+msgid "%s: uid %d is not unique\n"
+msgstr "%s: uid %d är inte unikt\n"
+
+#: src/useradd.c:1031
+#, c-format
+msgid "%s: can't get unique uid\n"
+msgstr "%s: kan inte hitta ett unikt uid\n"
+
+#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057
+#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157
+#, c-format
+msgid "%s: invalid field `%s'\n"
+msgstr "%s: felaktigt fält \"%s\"\n"
+
+#: src/useradd.c:1153
+#, c-format
+msgid "%s: invalid base directory `%s'\n"
+msgstr "%s: felaktig baskatalog \"%s\"\n"
+
+#: src/useradd.c:1163
+#, c-format
+msgid "%s: invalid comment `%s'\n"
+msgstr "%s: felaktig kommentar \"%s\"\n"
+
+#: src/useradd.c:1173
+#, c-format
+msgid "%s: invalid home directory `%s'\n"
+msgstr "%s: felaktig hemkatalog \"%s\"\n"
+
+#: src/useradd.c:1191 src/usermod.c:1080
+#, c-format
+msgid "%s: invalid date `%s'\n"
+msgstr "%s: felaktigt datum \"%s\"\n"
+
+#: src/useradd.c:1203
+#, c-format
+msgid "%s: shadow passwords required for -e\n"
+msgstr "%s: skugglösenord krävs för -e\n"
+
+#: src/useradd.c:1218
+#, c-format
+msgid "%s: shadow passwords required for -f\n"
+msgstr "%s: skugglösenord krävs för -f\n"
+
+#: src/useradd.c:1292
+#, c-format
+msgid "%s: invalid shell `%s'\n"
+msgstr "%s: felaktigt skal \"%s\"\n"
+
+#: src/useradd.c:1333
+#, c-format
+msgid "%s: invalid user name `%s'\n"
+msgstr "%s: felaktigt användar namn \"%s\"\n"
+
+#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225
+#, c-format
+msgid "%s: cannot rewrite password file\n"
+msgstr "%s: kan inte skriva om lösenordsfilen\n"
+
+#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230
+#, c-format
+msgid "%s: cannot rewrite shadow password file\n"
+msgstr "%s: kan inte skriva om skugglösenordsfilen\n"
+
+#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265
+#, c-format
+msgid "%s: unable to lock password file\n"
+msgstr "%s: kan inte låsa lösenordsfilen\n"
+
+#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269
+#, c-format
+msgid "%s: unable to open password file\n"
+msgstr "%s: kan inte öppna lösenordsfilen\n"
+
+#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274
+#, c-format
+msgid "%s: cannot lock shadow password file\n"
+msgstr "%s: kan inte låsa skugglösenordsfilen\n"
+
+#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279
+#, c-format
+msgid "%s: cannot open shadow password file\n"
+msgstr "%s: kan inte öppna skugglösenordsfilen\n"
+
+#: src/useradd.c:1529 src/usermod.c:1366
+#, c-format
+msgid "%s: error adding authentication method\n"
+msgstr "%s: fel under tillägning av metod för äkthetsbevisning\n"
+
+#: src/useradd.c:1552
+#, c-format
+msgid "%s: error adding new password entry\n"
+msgstr "%s: fel under tilläggning av ny lösenordsnotering\n"
+
+#: src/useradd.c:1567
+#, c-format
+msgid "%s: error updating password dbm entry\n"
+msgstr "%s: fel under uppdatering av dbm-lösenordsnotering\n"
+
+#: src/useradd.c:1583 src/usermod.c:1425
+#, c-format
+msgid "%s: error adding new shadow password entry\n"
+msgstr "%s: fel under tilläggning av ny skugglösenordsnotering\n"
+
+#: src/useradd.c:1599 src/usermod.c:1440
+#, c-format
+msgid "%s: error updating shadow passwd dbm entry\n"
+msgstr "%s: fel under uppdatering av dbm-skugglösenordsnotering\n"
+
+#: src/useradd.c:1631
+#, c-format
+msgid "%s: cannot create directory %s\n"
+msgstr "%s: kan inte skapa katalog %s\n"
+
+#: src/useradd.c:1708 src/usermod.c:1203
+#, c-format
+msgid "%s: user %s exists\n"
+msgstr "%s: användare %s existerar\n"
+
+#: src/useradd.c:1738
+#, c-format
+msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n"
+msgstr "%s: varning: CREATE_HOME stöds inte, använd -m istället.\n"
+
+#: src/userdel.c:127
+#, c-format
+msgid "usage: %s [-r] name\n"
+msgstr "Användning: %s [-r] namn\n"
+
+#: src/userdel.c:178 src/userdel.c:260
+#, c-format
+msgid "%s: error updating group entry\n"
+msgstr "%s: fel under uppdatering av gruppnotering\n"
+
+#: src/userdel.c:188 src/userdel.c:269
+#, c-format
+msgid "%s: cannot update dbm group entry\n"
+msgstr "%s: kan inte uppdatera dbm-gruppnotering\n"
+
+#: src/userdel.c:215
+#, fuzzy, c-format
+msgid "%s: cannot remove dbm group entry\n"
+msgstr "%s: kan inte uppdatera dbm-gruppnotering\n"
+
+#: src/userdel.c:300
+#, c-format
+msgid "%s: cannot rewrite TCFS key file\n"
+msgstr "%s: kan inte skriva om TCFS-nyckelfilen\n"
+
+#: src/userdel.c:380
+#, c-format
+msgid "%s: cannot lock TCFS key file\n"
+msgstr "%s: kan inte låsa TCFS-nyckelfilen\n"
+
+#: src/userdel.c:384
+#, c-format
+msgid "%s: cannot open TCFS key file\n"
+msgstr "%s: kan inte öppna TCFS-nyckelfilen\n"
+
+#: src/userdel.c:393
+#, c-format
+msgid "%s: cannot open group file\n"
+msgstr "%s: kan inte öppna gruppfilen\n"
+
+#: src/userdel.c:403
+#, c-format
+msgid "%s: cannot open shadow group file\n"
+msgstr "%s: kan inte öppna skuggruppfilen\n"
+
+#: src/userdel.c:434 src/userdel.c:449
+#, c-format
+msgid "%s: error deleting authentication\n"
+msgstr "%s: fel under borttagning av metod för äkthetsbevisning\n"
+
+#: src/userdel.c:458
+#, c-format
+msgid "%s: error deleting password entry\n"
+msgstr "%s: fel under borttagning av lösenordsnotering\n"
+
+#: src/userdel.c:461
+#, c-format
+msgid "%s: error deleting shadow password entry\n"
+msgstr "%s: fel under borttagning av skugglösenordsnotering\n"
+
+#: src/userdel.c:470
+#, c-format
+msgid "%s: error deleting TCFS entry\n"
+msgstr "%s: fel under borttagning av TCFS-notering\n"
+
+#: src/userdel.c:483
+#, c-format
+msgid "%s: error deleting password dbm entry\n"
+msgstr "%s: fel under borttagning av dbm-lösenordsnotering\n"
+
+#: src/userdel.c:502
+#, c-format
+msgid "%s: error deleting shadow passwd dbm entry\n"
+msgstr "%s: fel under borttagning av dbm-skugglösenordsnotering\n"
+
+#: src/userdel.c:543
+#, c-format
+msgid "%s: user %s is currently logged in\n"
+msgstr "%s: användare %s är inloggad\n"
+
+#: src/userdel.c:660
+#, c-format
+msgid "%s: warning: %s not owned by %s, not removing\n"
+msgstr "%s: varning: %s ägs inte av %s, tar inte bort\n"
+
+#: src/userdel.c:666
+#, c-format
+msgid "%s: warning: can't remove "
+msgstr "%s: varning: kan inte ta bort "
+
+#: src/userdel.c:741 src/usermod.c:994
+#, c-format
+msgid "%s: user %s does not exist\n"
+msgstr "%s: användare %s finns inte\n"
+
+#: src/userdel.c:755 src/usermod.c:1010
+#, c-format
+msgid "%s: user %s is a NIS user\n"
+msgstr "%s: användare %s är en NIS-användare\n"
+
+#: src/userdel.c:792
+#, c-format
+msgid "%s: %s not owned by %s, not removing\n"
+msgstr "%s: %s ägs inte av %s, tar inte bort\n"
+
+#: src/userdel.c:815
+#, c-format
+msgid "%s: not removing directory %s (would remove home of user %s)\n"
+msgstr "%s: tar inte bort katalogen %s (skulle ta bort hemkatalogen för %s)\n"
+
+#: src/userdel.c:828
+#, c-format
+msgid "%s: error removing directory %s\n"
+msgstr "%s: fel under borttagning av katalogen %s\n"
+
+#: src/usermod.c:317
+msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"
+msgstr "\t\t[-d hem [-m]] [-s skal] [-c kommentar] [-l nytt_namn]\n"
+
+#: src/usermod.c:323
+msgid "[-A {DEFAULT|program},... ] "
+msgstr "[-A {DEFAULT|program},... ] "
+
+#: src/usermod.c:325
+#, fuzzy
+msgid "[-p passwd] [-L|-U] name\n"
+msgstr "[-p passwd] namn\n"
+
+#: src/usermod.c:504
+#, c-format
+msgid "%s: out of memory in update_group\n"
+msgstr "%s: slut på minne i update_group\n"
+
+#: src/usermod.c:627
+#, c-format
+msgid "%s: out of memory in update_gshadow\n"
+msgstr "%s: slut på minne i update_gshadow\n"
+
+#: src/usermod.c:1180
+#, c-format
+msgid "%s: no flags given\n"
+msgstr "%s: inga flaggor givna\n"
+
+#: src/usermod.c:1187
+#, c-format
+msgid "%s: shadow passwords required for -e and -f\n"
+msgstr "%s: skugglösenord krävs för -e och -f\n"
+
+#: src/usermod.c:1208
+#, c-format
+msgid "%s: uid %ld is not unique\n"
+msgstr "%s: uid %ld är inte unikt\n"
+
+#: src/usermod.c:1356
+#, c-format
+msgid "%s: error deleting authentication method\n"
+msgstr "%s: fel under borttagning av metod för äkthetsbevisning\n"
+
+#: src/usermod.c:1376
+#, c-format
+msgid "%s: error changing authentication method\n"
+msgstr "%s: fel under ändring av metod för äkthetsbevisning\n"
+
+#: src/usermod.c:1393
+#, c-format
+msgid "%s: error changing password entry\n"
+msgstr "%s: fel under ändring av lösenordsnotering\n"
+
+#: src/usermod.c:1399
+#, c-format
+msgid "%s: error removing password entry\n"
+msgstr "%s: fel under borttagning av lösenordsnotering\n"
+
+#: src/usermod.c:1407
+#, c-format
+msgid "%s: error adding password dbm entry\n"
+msgstr "%s: fel under tilläggning av dbm-lösenordsnotering\n"
+
+#: src/usermod.c:1414
+#, c-format
+msgid "%s: error removing passwd dbm entry\n"
+msgstr "%s: fel under borttagning av dbm-lösenordsnotering\n"
+
+#: src/usermod.c:1431
+#, c-format
+msgid "%s: error removing shadow password entry\n"
+msgstr "%s: fel under borttagning av skugglösenordsnotering\n"
+
+#: src/usermod.c:1446
+#, c-format
+msgid "%s: error removing shadow passwd dbm entry\n"
+msgstr "%s: fel under borttagning av dbm-skugglösenordsnotering\n"
+
+#: src/usermod.c:1477
+#, c-format
+msgid "%s: directory %s exists\n"
+msgstr "%s: katalogen %s existerar\n"
+
+#: src/usermod.c:1484
+#, c-format
+msgid "%s: can't create %s\n"
+msgstr "%s: kan inte skapa %s\n"
+
+#: src/usermod.c:1490
+#, c-format
+msgid "%s: can't chown %s\n"
+msgstr "%s: kan inte byta ägare på %s\n"
+
+#: src/usermod.c:1506
+#, c-format
+msgid "%s: cannot rename directory %s to %s\n"
+msgstr "%s: kan inte byta namn på katalogen %s till %s\n"
+
+#. better leave it alone
+#: src/usermod.c:1603
+#, c-format
+msgid "%s: warning: %s not owned by %s\n"
+msgstr "%s: varning: %s ägs inte av %s\n"
+
+#: src/usermod.c:1609
+msgid "failed to change mailbox owner"
+msgstr "kunde inte byta ägare av brevlådan"
+
+#: src/usermod.c:1616
+msgid "failed to rename mailbox"
+msgstr "kunde inte byta namn på brevlådan"
+
+#: src/vipw.c:102
+#, c-format
+msgid ""
+"\n"
+"%s: %s is unchanged\n"
+msgstr ""
+"\n"
+"%s: %s är oförändrad\n"
+
+#: src/vipw.c:127
+msgid "Couldn't lock file"
+msgstr "Kunde inte låsa filen"
+
+#: src/vipw.c:134
+msgid "Couldn't make backup"
+msgstr "Kunde inte göra en backup"
+
+#: src/vipw.c:187
+#, c-format
+msgid "%s: can't restore %s: %s (your changes are in %s)\n"
+msgstr "%s: kan inte återställa %s: %s (dina ändringar är i %s)\n"
+
+#: src/vipw.c:226
+msgid ""
+"Usage:\n"
+"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n"
+"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n"
+msgstr ""
+"Användning:\n"
+"\"vipw\" editerar /etc/passwd \"vipw -w\" editerar /etc/shadow\n"
+"\"vipg\" editerar /etc/group \"vipg -w\" editerar /etc/gshadow\n"
diff --git a/current/redhat/Makefile.am b/current/redhat/Makefile.am
new file mode 100644
index 00000000..4e9ac2fa
--- /dev/null
+++ b/current/redhat/Makefile.am
@@ -0,0 +1,8 @@
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+EXTRA_DIST = README shadow-utils.spec shadow-utils.spec.in \
+ shadow-970616-fix.patch shadow-970616-glibc.patch \
+ shadow-970616-rh.patch shadow-970616-utuser.patch \
+ shadow-970616.login.defs shadow-970616.useradd \
+ shadow-utils-970616.spec
diff --git a/current/redhat/Makefile.in b/current/redhat/Makefile.in
new file mode 100644
index 00000000..7aa97334
--- /dev/null
+++ b/current/redhat/Makefile.in
@@ -0,0 +1,214 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This is a dummy Makefile.am to get automake work flawlessly,
+# and also cooperate to make a distribution for `make dist'
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+EXTRA_DIST = README shadow-utils.spec shadow-utils.spec.in shadow-970616-fix.patch shadow-970616-glibc.patch shadow-970616-rh.patch shadow-970616-utuser.patch shadow-970616.login.defs shadow-970616.useradd shadow-utils-970616.spec
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = shadow-utils.spec
+DIST_COMMON = README Makefile.am Makefile.in shadow-utils.spec.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps redhat/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+shadow-utils.spec: $(top_builddir)/config.status shadow-utils.spec.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = redhat
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/redhat/README b/current/redhat/README
new file mode 100644
index 00000000..96739e7f
--- /dev/null
+++ b/current/redhat/README
@@ -0,0 +1,29 @@
+Included here are the patches from the shadow-utils-970616-11.src.rpm
+(RedHat 5.0 updates). I'd like to make it possible to build binary
+packages for all Linux distributions "out of the box" from the same
+upstream sources. This needs more work for RedHat 5.0, and I only have
+RedHat 4.2 (hint hint). If you have any suggestions regarding this
+package, please contact me. Perhaps the necessary changes can be
+included in the standard sources, so that everything can be build with
+one simple command (rpm -ta shadow-xxxxxx.tar.gz).
+
+One suggestion for the shadow-utils-970616-11 patch: instead of adding
+new (sometimes quite distribution-specific) options to useradd (and
+symlinking adduser -> useradd), I'd suggest to use a program or script
+called "adduser" that implements the distribution-specific UID/GID
+allocation etc. and runs useradd to do all the dirty work (modifying
+password files etc.). Also, please don't change the default behaviour
+of useradd, which is to create the home directory only if the -m option
+is specified). I'd like to keep useradd simple, and compatible with
+other implementations (the user* and group* commands are quite similar
+to commands with the same names found on many commercial UN*X systems).
+
+I'd suggest to take a look at the adduser-3.x package from the Debian
+distribution. It's a perl script, which shouldn't be too hard to modify
+to suit the requirements of Red Hat, or any other Linux distribution.
+It runs programs from the shadow suite to do the actual password file
+modifications, is reasonably user friendly, and configurable.
+
+Comments?
+
+--marekm
diff --git a/current/redhat/shadow-970616-fix.patch b/current/redhat/shadow-970616-fix.patch
new file mode 100644
index 00000000..341f11a4
--- /dev/null
+++ b/current/redhat/shadow-970616-fix.patch
@@ -0,0 +1,256 @@
+--- shadow-970616/libmisc/Makefile.in.fix Sun Jun 15 20:05:05 1997
++++ shadow-970616/libmisc/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -99,13 +99,6 @@
+
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+-
+ mostlyclean-noinstLIBRARIES:
+
+ clean-noinstLIBRARIES:
+--- shadow-970616/man/Makefile.in.fix Sun Jun 15 20:05:05 1997
++++ shadow-970616/man/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -72,12 +72,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ install-man: $(MANS)
+ $(mkinstalldirs) $(mandir)/man8
+ $(mkinstalldirs) $(mandir)/man1
+--- shadow-970616/lib/Makefile.in.fix Sun Jun 15 20:05:06 1997
++++ shadow-970616/lib/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -123,12 +123,6 @@
+ default: all
+
+
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+-
+ mostlyclean-noinstLIBRARIES:
+
+ clean-noinstLIBRARIES:
+--- shadow-970616/src/useradd.c.fix Tue Dec 30 14:09:29 1997
++++ shadow-970616/src/useradd.c Tue Dec 30 14:37:22 1997
+@@ -570,8 +570,7 @@
+ */
+
+ static int
+-get_groups(list)
+- char *list;
++get_groups(char *list)
+ {
+ char *cp;
+ const struct group *grp;
+@@ -606,7 +605,7 @@
+ * GID values, otherwise the string is looked up as is.
+ */
+
+- grp = getgr_nam_gid(*list);
++ grp = getgr_nam_gid(list);
+
+ /*
+ * There must be a match, either by GID value or by
+@@ -1401,25 +1400,6 @@
+ Prog);
+ fail_exit (1);
+ }
+-#endif
+- if (do_grp_update) {
+- if (! gr_close ()) {
+- fprintf (stderr, "%s: cannot rewrite group file\n",
+- Prog);
+- fail_exit (1);
+- }
+- (void) gr_unlock ();
+-#ifdef SHADOWGRP
+- if (is_shadow_grp && ! sgr_close ()) {
+- fprintf (stderr, "%s: cannot rewrite shadow group file\n",
+- Prog);
+- fail_exit (1);
+- }
+- if (is_shadow_grp)
+- sgr_unlock ();
+-#endif
+- }
+-#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ spw_unlock ();
+ #endif
+@@ -1758,7 +1738,6 @@
+ /*
+ * Write out the new group file entry.
+ */
+-
+ if (! gr_update (&grp)) {
+ fprintf (stderr, "%s: error adding new group entry\n", Prog);
+ fail_exit (10);
+@@ -1801,6 +1780,8 @@
+ #endif /* SHADOWGRP */
+ SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n",
+ user_name, user_gid));
++ /* we need to remeber we have to close the group file... */
++ do_grp_update++;
+ }
+
+ /*
+--- shadow-970616/src/Makefile.in.fix Sun Jun 15 20:05:08 1997
++++ shadow-970616/src/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -251,12 +251,6 @@
+ default: all
+
+
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+-
+ mostlyclean-usbinPROGRAMS:
+
+ clean-usbinPROGRAMS:
+--- shadow-970616/contrib/Makefile.in.fix Sun Jun 15 20:05:09 1997
++++ shadow-970616/contrib/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -60,12 +60,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ tags: TAGS
+ TAGS:
+
+--- shadow-970616/debian/Makefile.in.fix Sun Jun 15 20:05:09 1997
++++ shadow-970616/debian/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -64,12 +64,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ tags: TAGS
+ TAGS:
+
+--- shadow-970616/doc/Makefile.in.fix Sun Jun 15 20:05:09 1997
++++ shadow-970616/doc/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -61,12 +61,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ tags: TAGS
+ TAGS:
+
+--- shadow-970616/etc/Makefile.in.fix Sun Jun 15 20:05:09 1997
++++ shadow-970616/etc/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -60,12 +60,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ tags: TAGS
+ TAGS:
+
+--- shadow-970616/old/Makefile.in.fix Sun Jun 15 20:05:10 1997
++++ shadow-970616/old/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -61,12 +61,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ tags: TAGS
+ TAGS:
+
+--- shadow-970616/shlib/Makefile.in.fix Sun Jun 15 20:05:10 1997
++++ shadow-970616/shlib/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -60,11 +60,6 @@
+ default: all
+
+
+-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
+- cd $(top_srcdir) && automake $(subdir)/Makefile
+-
+-Makefile: $(top_builddir)/config.status Makefile.in
+- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ tags: TAGS
+ TAGS:
+
+--- shadow-970616/configure.in.fix Sun Jun 15 19:42:47 1997
++++ shadow-970616/configure.in Tue Dec 30 14:09:29 1997
+@@ -38,7 +38,7 @@
+ AC_CHECK_HEADERS(gshadow.h shadow.h lastlog.h)
+
+ AC_EGREP_HEADER(ut_host, utmp.h, AC_DEFINE(UT_HOST))
+-AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_name))
++AC_EGREP_HEADER(ut_user, utmp.h, AC_DEFINE(UT_USER, ut_user))
+ AC_EGREP_HEADER(ll_host, lastlog.h, AC_DEFINE(HAVE_LL_HOST))
+
+ dnl Checks for typedefs, structures, and compiler characteristics.
+--- shadow-970616/Makefile.in.fix Sun Jun 15 20:05:08 1997
++++ shadow-970616/Makefile.in Tue Dec 30 14:09:29 1997
+@@ -64,28 +64,6 @@
+ TAR = tar
+ default: all
+
+-
+-$(srcdir)/Makefile.in: Makefile.am configure.in
+- cd $(srcdir) && automake Makefile
+-
+-# For an explanation of the following Makefile rules, see node
+-# `Automatic Remaking' in GNU Autoconf documentation.
+-Makefile: Makefile.in config.status
+- CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+-config.status: configure
+- ./config.status --recheck
+-$(srcdir)/configure: configure.in $(ACLOCAL) $(CONFIGURE_DEPENDENCIES)
+- cd $(srcdir) && autoconf
+-
+-$(CONFIG_HEADER): stamp-h
+-stamp-h: $(CONFIG_HEADER_IN) config.status
+- CONFIG_FILES= CONFIG_HEADERS=$(CONFIG_HEADER) ./config.status
+- @echo timestamp > stamp-h
+-$(srcdir)/$(CONFIG_HEADER_IN): stamp-h.in
+-$(srcdir)/stamp-h.in: configure.in $(ACLOCAL) $(ACCONFIG) $(CONFIG_TOP) $(CONFIG_BOT)
+- cd $(srcdir) && autoheader
+- echo timestamp > $(srcdir)/stamp-h.in
+-
+ # This directory's subdirectories are mostly independent; you can cd
+ # into them and run `make' without going through this Makefile.
+ # To change the values of `make' variables: instead of editing Makefiles,
diff --git a/current/redhat/shadow-970616-glibc.patch b/current/redhat/shadow-970616-glibc.patch
new file mode 100644
index 00000000..ecd7039e
--- /dev/null
+++ b/current/redhat/shadow-970616-glibc.patch
@@ -0,0 +1,11 @@
+--- shadow-970616/libmisc/strtoday.c.ewt Thu Nov 13 19:25:25 1997
++++ shadow-970616/libmisc/strtoday.c Thu Nov 13 19:27:57 1997
+@@ -28,7 +28,7 @@
+ */
+
+ #if !defined(__GLIBC__)
+-#define _XOPEN_SOURCE
++#define _XOPEN_SOURCE 500
+ #endif
+
+ #include <config.h>
diff --git a/current/redhat/shadow-970616-rh.patch b/current/redhat/shadow-970616-rh.patch
new file mode 100644
index 00000000..3b3e34d3
--- /dev/null
+++ b/current/redhat/shadow-970616-rh.patch
@@ -0,0 +1,1242 @@
+--- shadow-970616/man/shadowconfig.8.rh Thu May 1 14:18:17 1997
++++ shadow-970616/man/shadowconfig.8 Fri Dec 12 15:36:29 1997
+@@ -14,7 +14,3 @@
+ will print an error message and exit with a nonzero code if it finds
+ anything awry. If that happens, you should correct the error and run
+ it again.
+-.PP
+-Read
+-.I /usr/doc/passwd/README.debian.gz
+-for a brief introduction to shadow passwords and related features.
+--- shadow-970616/man/useradd.8.rh Thu May 1 19:15:12 1997
++++ shadow-970616/man/useradd.8 Fri Dec 12 15:36:29 1997
+@@ -50,13 +50,15 @@
+ .RB [ -G
+ .IR group [,...]]
+ .RB [ -m " [" -k
+-.IR skeleton_dir ]]
++.IR skeleton_dir ] " |" " " -M ]
+ .RB [ -s
+ .IR shell ]
+ .br
+ .RB [ -u
+ .IR uid " ["
+ .BR -o ]]
++.RB [ -n ]
++.RB [ -r ]
+ .I login
+ .TP 8
+ .B useradd
+@@ -81,6 +83,8 @@
+ The new user account will be entered into the system files as needed,
+ the home directory will be created, and initial files copied, depending
+ on the command line options.
++The version provided with Red Hat Linux will create a group for each
++user added to the system, unless \fB-n\fR option is given.
+ The options which apply to the \fBuseradd\fR command are
+ .IP "\fB-A {\fImethod\fR|\fBDEFAULT\fR},..."
+ The value of the user's authentication method.
+@@ -128,6 +132,21 @@
+ option.
+ The default is to not create the directory and to not copy any
+ files.
++.IP \fB-M\fR
++The user home directory will not be created, even if the system
++wide settings from \fI/etc/login.defs\fR is to create home dirs.
++.IP \fB-n\fR
++A group having the same name as the user being added to the system
++will be created by default. This option will turn off this Red Hat
++Linux specific behavior.
++.IP \fB-r\fR
++This flag is used to create a system account. That is, an user with an
++UID lower than value of UID_MIN defined in \fI/etc/login.defs\fR. Note
++that \fBuseradd\fR will not create a home directory for such an user,
++regardless of the default setting in \fI/etc/login.defs\fR.
++You have to specify \fB-m\fR option if you want a home directory
++for a system account to be created.
++This is an option added by Red Hat.
+ .IP "\fB-s \fIshell\fR"
+ The name of the user's login shell.
+ The default is to leave this field blank, which causes the system
+@@ -168,19 +187,24 @@
+ .SH NOTES
+ The system administrator is responsible for placing the default
+ user files in the \fI/etc/skel\fR directory.
++.br
++This version of useradd was modified by Red Hat to suit Red Hat
++user/group convention.
+ .SH CAVEATS
+ You may not add a user to an NIS group.
+ This must be performed on the NIS server.
+ .SH FILES
+-/etc/passwd \- user account information
++\fB/etc/passwd\fR \- user account information
++.br
++\fB/etc/shadow\fR \- secure user account information
+ .br
+-/etc/shadow \- secure user account information
++\fB/etc/group\fR \- group information
+ .br
+-/etc/group \- group information
++\fB/etc/default/useradd\fR \- default information
+ .br
+-/etc/default/useradd \- default information
++\fB/etc/login.defs\fR \- system-wide settings
+ .br
+-/etc/skel \- directory containing default files
++\fB/etc/skel\fR \- directory containing default files
+ .SH SEE ALSO
+ .BR chfn (1),
+ .BR chsh (1),
+--- shadow-970616/man/groupadd.8.rh Thu May 1 19:15:06 1997
++++ shadow-970616/man/groupadd.8 Fri Dec 12 15:36:29 1997
+@@ -32,7 +32,7 @@
+ groupadd \- Create a new group
+ .SH SYNOPSIS
+ .B groupadd
+-[\fB-g\fI gid \fR[\fB-o\fR]]
++[\fB-g\fI gid \fR[\fB-o\fR]] [\fB-r\fR] [\fB-f\fR]
+ .I group
+ .SH DESCRIPTION
+ The \fBgroupadd\fR command
+@@ -44,9 +44,29 @@
+ The numerical value of the group's ID.
+ This value must be unique, unless the \fB-o\fR option is used.
+ The value must be non-negative.
+-The default is to use the smallest ID value greater than 99 and
++The default is to use the smallest ID value greater than 500 and
+ greater than every other group.
+-Values between 0 and 99 are typically reserved for system accounts.
++Values between 0 and 499 are typically reserved for \fIsystem accounts\fR.
++.IP \fB-r\fR
++This flag instructs \fBgroupadd\fR to add a \fIsystem
++account\fR. First available \fIgid\fR lower than 499 will be
++automatically selected unless \fB-g\fR option is given also on the
++command line.
++.br
++This is an option added by Red Hat Software.
++.IP \fB-f\fR
++This is \fIforce\fR flag. This will stop \fBgroupadd\fR exit with
++error when the group about to be added already exists on the
++system. If that is the case, the group won't be altered (or added
++again, for that matter).
++.br
++This option also modifies the way \fB-g\fR option works. When you
++request a \fIgid\fR that it is not unique and you don't give \fB-o\fR
++option too, the group creation will fall back to the standard behavior
++(adding a group as neither \fB-g\fR or \fB-o\fR options were
++specified).
++.br
++This is an option added by Red Hat Software.
+ .SH FILES
+ /etc/group \- group account information
+ .br
+--- shadow-970616/lib/getdef.c.rh Thu May 1 19:14:40 1997
++++ shadow-970616/lib/getdef.c Fri Dec 12 15:36:29 1997
+@@ -61,6 +61,7 @@
+ #ifdef HAVE_LIBCRACK
+ { "CRACKLIB_DICTPATH", NULL },
+ #endif
++ { "CREATE_HOME", NULL },
+ { "DEFAULT_HOME", NULL },
+ { "DIALUPS_CHECK_ENAB", NULL },
+ { "ENVIRON_FILE", NULL },
+@@ -171,7 +172,7 @@
+ if ((d = def_find(item)) == NULL || d->value == NULL)
+ return 0;
+
+- return (strcmp(d->value, "yes") == 0);
++ return (strcasecmp(d->value, "yes") == 0);
+ }
+
+
+--- shadow-970616/src/useradd.c.rh Sun Jun 1 01:25:40 1997
++++ shadow-970616/src/useradd.c Fri Dec 12 15:58:04 1997
+@@ -60,7 +60,7 @@
+ #define USER_DEFAULTS_FILE "/etc/default/useradd"
+ #define NEW_USER_FILE "/etc/default/nuaddXXXXXX"
+ #endif
+-
++
+ /*
+ * Needed for MkLinux DR1/2/2.1 - J.
+ */
+@@ -71,22 +71,22 @@
+ /*
+ * These defaults are used if there is no defaults file.
+ */
+-static gid_t def_group = 1;
++static gid_t def_group = 100;
+ static char *def_gname = "other";
+ static char *def_home = "/home";
+-static char *def_shell = "";
++static char *def_shell = "/dev/null";
+ static char *def_template = SKEL_DIR;
+ #ifdef SHADOWPWD
+ static long def_inactive = -1;
+ static char *def_expire = "";
+ #endif
+
+-static char def_file[] = USER_DEFAULTS_FILE;
++static char def_file[] = USER_DEFAULTS_FILE;
+
+ #define VALID(s) (strcspn (s, ":\n") == strlen (s))
+
+ static char *user_name = "";
+-static char *user_pass = "!";
++static char *user_pass = "!!";
+ static uid_t user_id;
+ static gid_t user_gid;
+ static char *user_comment = "";
+@@ -114,10 +114,13 @@
+ sflg = 0, /* shell program for new account */
+ cflg = 0, /* comment (GECOS) field for new account */
+ mflg = 0, /* create user's home directory if it doesn't exist */
+- kflg = 0, /* specify a directory to fill new user directory */
++ Mflg = 0, /* do NOT create user's home directory no matter what */
++ kflg = 0, /* specify a directory to fill new user directory */
+ fflg = 0, /* days until account with expired password is locked */
+ eflg = 0, /* days since 1970-01-01 when account is locked */
+- Dflg = 0; /* set/show new user default values */
++ Dflg = 0, /* set/show new user default values */
++ nflg = 0, /* do not add a group for this user */
++ rflg = 0; /* create a system account */
+
+ #ifdef AUTH_METHODS
+ static int Aflg = 0; /* specify authentication method for user */
+@@ -168,6 +171,7 @@
+ * exit status values
+ */
+ #define E_SUCCESS 0 /* success */
++#define E_LOCKING 1 /* locking error */
+ #define E_USAGE 2 /* bad command syntax */
+ #define E_BAD_ARG 3 /* invalid argument to option */
+ #define E_UID_IN_USE 4 /* uid already in use (and no -o) */
+@@ -177,19 +181,19 @@
+ #define E_HOMEDIR 12 /* can't create home directory */
+
+ #ifdef SVR4
+-#define DGROUP "defgroup="
+-#define HOME "defparent="
+-#define SHELL "defshell="
+-#define INACT "definact="
+-#define EXPIRE "defexpire="
+-#define SKEL "defskel="
++#define DGROUP "defgroup="
++#define HOME "defparent="
++#define SHELL "defshell="
++#define INACT "definact="
++#define EXPIRE "defexpire="
++#define SKEL "defskel="
+ #else
+-#define DGROUP "GROUP="
+-#define HOME "HOME="
+-#define SHELL "SHELL="
+-#define INACT "INACTIVE="
+-#define EXPIRE "EXPIRE="
+-#define SKEL "SKEL="
++#define DGROUP "GROUP="
++#define HOME "HOME="
++#define SHELL "SHELL="
++#define INACT "INACTIVE="
++#define EXPIRE "EXPIRE="
++#define SKEL "SKEL="
+ #endif
+
+ /*
+@@ -679,7 +683,7 @@
+ #ifdef AUTH_METHODS
+ fprintf(stderr, "[-A program] ");
+ #endif
+- fprintf(stderr, "[-p passwd] name\n");
++ fprintf(stderr, "[-p passwd] [-n] [-r] name\n");
+
+ fprintf(stderr, " %s\t-D [-g group] [-b base] [-s shell]"
+ #ifdef SHADOWPWD
+@@ -771,153 +775,129 @@
+ static void
+ grp_update()
+ {
+- const struct group *grp;
+- struct group *ngrp;
++ const struct group *grp;
++ struct group *ngrp;
+ #ifdef SHADOWGRP
+- const struct sgrp *sgrp;
+- struct sgrp *nsgrp;
++ const struct sgrp *sgrp;
++ struct sgrp *nsgrp;
+ #endif
+
+- /*
+- * Lock and open the group file. This will load all of the group
+- * entries.
+- */
++ /*
++ * Scan through the entire group file looking for the groups that
++ * the user is a member of.
++ */
+
+- if (! gr_lock ()) {
+- fprintf (stderr, "%s: error locking group file\n", Prog);
+- exit (1);
+- }
+- if (! gr_open (O_RDWR)) {
+- fprintf (stderr, "%s: error opening group file\n", Prog);
+- exit (1);
+- }
+-#ifdef SHADOWGRP
+- if (is_shadow_grp && ! sgr_lock ()) {
+- fprintf (stderr, "%s: error locking shadow group file\n", Prog);
+- exit (1);
+- }
+- if (is_shadow_grp && ! sgr_open (O_RDWR)) {
+- fprintf (stderr, "%s: error opening shadow group file\n", Prog);
+- exit (1);
+- }
+-#endif
++ for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
+
+ /*
+- * Scan through the entire group file looking for the groups that
+- * the user is a member of.
++ * See if the user specified this group as one of their
++ * concurrent groups.
+ */
+
+- for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
++ if (!is_on_list(user_groups, grp->gr_name))
++ continue;
+
+- /*
+- * See if the user specified this group as one of their
+- * concurrent groups.
+- */
+-
+- if (!is_on_list(user_groups, grp->gr_name))
+- continue;
+-
+- /*
+- * Make a copy - gr_update() will free() everything
+- * from the old entry, and we need it later.
+- */
++ /*
++ * Make a copy - gr_update() will free() everything
++ * from the old entry, and we need it later.
++ */
+
+- ngrp = __gr_dup(grp);
+- if (!ngrp) {
+- exit(13); /* XXX */
+- }
++ ngrp = __gr_dup(grp);
++ if (!ngrp) {
++ exit(13); /* XXX */
++ }
+
+- /*
+- * Add the username to the list of group members and
+- * update the group entry to reflect the change.
+- */
++ /*
++ * Add the username to the list of group members and
++ * update the group entry to reflect the change.
++ */
+
+- ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
+- if (! gr_update (ngrp)) {
+- fprintf (stderr, "%s: error adding new group entry\n",
+- Prog);
+- fail_exit (1);
+- }
++ ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
++ if (! gr_update (ngrp)) {
++ fprintf (stderr, "%s: error adding new group entry\n",
++ Prog);
++ fail_exit (1);
++ }
+ #ifdef NDBM
+- /*
+- * Update the DBM group file with the new entry as well.
+- */
++ /*
++ * Update the DBM group file with the new entry as well.
++ */
+
+- if (! gr_dbm_update (ngrp)) {
+- fprintf (stderr, "%s: cannot add new dbm group entry\n",
+- Prog);
+- fail_exit (1);
+- } else
+- gr_dbm_added++;
+-#endif
+- SYSLOG((LOG_INFO, "add `%s' to group `%s'\n",
+- user_name, ngrp->gr_name));
+- }
++ if (! gr_dbm_update (ngrp)) {
++ fprintf (stderr, "%s: cannot add new dbm group entry\n",
++ Prog);
++ fail_exit (1);
++ } else
++ gr_dbm_added++;
++#endif
++ SYSLOG((LOG_INFO, "add `%s' to group `%s'\n",
++ user_name, ngrp->gr_name));
++ }
+ #ifdef NDBM
+- endgrent ();
++ endgrent ();
+ #endif
+
+ #ifdef SHADOWGRP
+- if (!is_shadow_grp)
+- return;
++ if (!is_shadow_grp)
++ return;
+
+- /*
+- * Scan through the entire shadow group file looking for the groups
+- * that the user is a member of. The administrative list isn't
+- * modified.
+- */
++ /*
++ * Scan through the entire shadow group file looking for the groups
++ * that the user is a member of. The administrative list isn't
++ * modified.
++ */
+
+- for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
++ for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
+
+- /*
+- * See if the user specified this group as one of their
+- * concurrent groups.
+- */
++ /*
++ * See if the user specified this group as one of their
++ * concurrent groups.
++ */
+
+- if (!gr_locate(sgrp->sg_name))
+- continue;
++ if (!gr_locate(sgrp->sg_name))
++ continue;
+
+- if (!is_on_list(user_groups, sgrp->sg_name))
+- continue;
++ if (!is_on_list(user_groups, sgrp->sg_name))
++ continue;
+
+- /*
+- * Make a copy - sgr_update() will free() everything
+- * from the old entry, and we need it later.
+- */
++ /*
++ * Make a copy - sgr_update() will free() everything
++ * from the old entry, and we need it later.
++ */
+
+- nsgrp = __sgr_dup(sgrp);
+- if (!nsgrp) {
+- exit(13); /* XXX */
+- }
++ nsgrp = __sgr_dup(sgrp);
++ if (!nsgrp) {
++ exit(13); /* XXX */
++ }
+
+- /*
+- * Add the username to the list of group members and
+- * update the group entry to reflect the change.
+- */
++ /*
++ * Add the username to the list of group members and
++ * update the group entry to reflect the change.
++ */
+
+- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
+- if (! sgr_update (nsgrp)) {
+- fprintf (stderr, "%s: error adding new group entry\n",
+- Prog);
+- fail_exit (1);
+- }
++ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
++ if (! sgr_update (nsgrp)) {
++ fprintf (stderr, "%s: error adding new group entry\n",
++ Prog);
++ fail_exit (1);
++ }
+ #ifdef NDBM
+- /*
+- * Update the DBM group file with the new entry as well.
+- */
++ /*
++ * Update the DBM group file with the new entry as well.
++ */
+
+- if (! sg_dbm_update (nsgrp)) {
+- fprintf (stderr, "%s: cannot add new dbm group entry\n",
+- Prog);
+- fail_exit (1);
+- } else
+- sg_dbm_added++;
++ if (! sg_dbm_update (nsgrp)) {
++ fprintf (stderr, "%s: cannot add new dbm group entry\n",
++ Prog);
++ fail_exit (1);
++ } else
++ sg_dbm_added++;
+ #endif /* NDBM */
+- SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n",
+- user_name, nsgrp->sg_name));
+- }
++ SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n",
++ user_name, nsgrp->sg_name));
++ }
+ #ifdef NDBM
+- endsgent ();
++ endsgent ();
+ #endif /* NDBM */
+ #endif /* SHADOWGRP */
+ }
+@@ -936,8 +916,13 @@
+ const struct passwd *pwd;
+ uid_t uid_min, uid_max;
+
+- uid_min = getdef_num("UID_MIN", 100);
+- uid_max = getdef_num("UID_MAX", 60000);
++ if (!rflg) {
++ uid_min = getdef_num("UID_MIN", 500);
++ uid_max = getdef_num("UID_MAX", 60000);
++ } else {
++ uid_min = 1;
++ uid_max = 499;
++ }
+
+ /*
+ * Start with some UID value if the user didn't provide us with
+@@ -1003,6 +988,88 @@
+ }
+ }
+
++/*
++ * find_new_gid - find the next available GID
++ *
++ * find_new_gid() locates the next highest unused GID in the group
++ * file, or checks the given group ID against the existing ones for
++ * uniqueness.
++ */
++
++static void
++find_new_gid()
++{
++ const struct group *grp;
++ gid_t gid_min, gid_max;
++
++ if (!rflg) {
++ gid_min = getdef_num("GID_MIN", 500);
++ gid_max = getdef_num("GID_MAX", 60000);
++ } else {
++ gid_min = 1;
++ gid_max = 499;
++ }
++
++ /*
++ * Start with some GID value if the user didn't provide us with
++ * one already.
++ */
++
++ user_gid = gid_min;
++
++ /*
++ * Search the entire group file, either looking for this
++ * GID (if the user specified one with -g) or looking for the
++ * largest unused value.
++ */
++
++#ifdef NO_GETGRENT
++ gr_rewind();
++ while ((grp = gr_next()))
++#else
++ setgrent();
++ while ((grp = getgrent()))
++#endif
++ {
++ if (strcmp(user_name, grp->gr_name) == 0) {
++ user_gid = grp->gr_gid;
++ return;
++ }
++ if (grp->gr_gid >= user_gid) {
++ if (grp->gr_gid > gid_max)
++ continue;
++ user_gid = grp->gr_gid + 1;
++ }
++ }
++#ifndef NO_GETGRENT /* RH Linux does have this, so ... */
++ /* A quick test gets here: if the UID is available
++ * as a GID, go ahead and use it */
++ if (!getgrgid(user_id)) {
++ user_gid = user_id;
++ return;
++ }
++#endif
++ if (user_gid == gid_max + 1) {
++ for (user_gid = gid_min; user_gid < gid_max; user_gid++) {
++#ifdef NO_GETGRENT
++ gr_rewind();
++ while ((grp = gr_next()) && grp->gr_gid != user_gid)
++ ;
++ if (!grp)
++ break;
++#else
++ if (!getgrgid(user_gid))
++ break;
++#endif
++ }
++ if (user_gid == gid_max) {
++ fprintf(stderr, "%s: can't get unique gid (run out of GIDs)\n",
++ Prog);
++ fail_exit(4);
++ }
++ }
++}
++
+ #ifdef AUTH_METHODS
+ /*
+ * convert_auth - convert the argument list to a authentication list
+@@ -1099,9 +1166,9 @@
+ int arg;
+
+ #ifdef SHADOWPWD
+-#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:"
++#define FLAGS "A:Du:og:G:d:s:c:mMk:p:f:e:b:nr"
+ #else
+-#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:"
++#define FLAGS "A:Du:og:G:d:s:c:mMk:p:b:nr"
+ #endif
+ while ((arg = getopt(argc, argv, FLAGS)) != EOF) {
+ #undef FLAGS
+@@ -1251,6 +1318,15 @@
+ user_id = get_number(optarg);
+ uflg++;
+ break;
++ case 'n':
++ nflg++;
++ break;
++ case 'r':
++ rflg++;
++ break;
++ case 'M':
++ Mflg++;
++ break;
+ default:
+ usage ();
+ }
+@@ -1261,9 +1337,12 @@
+ * Certain options are only valid in combination with others.
+ * Check it here so that they can be specified in any order.
+ */
+- if ((oflg && !uflg) || (kflg && !mflg))
++ if (kflg && !mflg)
+ usage();
+
++ if (mflg && Mflg) /* the admin is not decided .. create or not ? */
++ usage();
++
+ /*
+ * Either -D or username is required. Defaults can be set with -D
+ * for the -b, -e, -f, -g, -s options only.
+@@ -1312,39 +1391,53 @@
+ static void
+ close_files()
+ {
+- if (! pw_close ()) {
+- fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
+- fail_exit (1);
+- }
++ if (! pw_close ()) {
++ fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
++ fail_exit (1);
++ }
+ #ifdef SHADOWPWD
+- if (is_shadow_pwd && ! spw_close ()) {
+- fprintf (stderr, "%s: cannot rewrite shadow password file\n",
+- Prog);
+- fail_exit (1);
++ if (is_shadow_pwd && ! spw_close ()) {
++ fprintf (stderr, "%s: cannot rewrite shadow password file\n",
++ Prog);
++ fail_exit (1);
++ }
++#endif
++ if (do_grp_update) {
++ if (! gr_close ()) {
++ fprintf (stderr, "%s: cannot rewrite group file\n",
++ Prog);
++ fail_exit (1);
+ }
+-#endif
+- if (do_grp_update) {
+- if (! gr_close ()) {
+- fprintf (stderr, "%s: cannot rewrite group file\n",
+- Prog);
+- fail_exit (1);
+- }
+- (void) gr_unlock ();
++ (void) gr_unlock ();
+ #ifdef SHADOWGRP
+- if (is_shadow_grp && ! sgr_close ()) {
+- fprintf (stderr, "%s: cannot rewrite shadow group file\n",
+- Prog);
+- fail_exit (1);
+- }
+- if (is_shadow_grp)
+- sgr_unlock ();
+-#endif
++ if (is_shadow_grp && ! sgr_close ()) {
++ fprintf (stderr, "%s: cannot rewrite shadow group file\n",
++ Prog);
++ fail_exit (1);
+ }
++ if (is_shadow_grp)
++ sgr_unlock ();
++#endif
++ }
+ #ifdef SHADOWPWD
+- if (is_shadow_pwd)
+- spw_unlock ();
++ if (is_shadow_pwd)
++ spw_unlock ();
+ #endif
+- (void) pw_unlock ();
++ (void) pw_unlock ();
++ if (! gr_close ()) {
++ fprintf (stderr, "%s: cannot rewrite group file\n", Prog);
++ fail_exit (10);
++ }
++ (void) gr_unlock ();
++#ifdef SHADOWGRP
++ if (is_shadow_grp && ! sgr_close ()) {
++ fprintf (stderr, "%s: cannot rewrite shadow group file\n",
++ Prog);
++ fail_exit (10);
++ }
++ if (is_shadow_grp)
++ sgr_unlock ();
++#endif /* SHADOWGRP */
+ }
+
+ /*
+@@ -1353,27 +1446,47 @@
+ * open_files() opens the two password files.
+ */
+
+-static void
+-open_files()
++static void open_files(void)
+ {
+- if (!pw_lock_first()) {
+- fprintf (stderr, "%s: unable to lock password file\n", Prog);
+- exit (1);
+- }
+- if (! pw_open (O_RDWR)) {
+- fprintf (stderr, "%s: unable to open password file\n", Prog);
+- exit (1);
+- }
++ if (!pw_lock_first()) {
++ fprintf (stderr, "%s: unable to lock password file\n", Prog);
++ exit (1);
++ }
++ if (! pw_open (O_RDWR)) {
++ fprintf (stderr, "%s: unable to open password file\n", Prog);
++ exit (1);
++ }
+ #ifdef SHADOWPWD
+- if (is_shadow_pwd && ! spw_lock ()) {
+- fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
+- exit (1);
+- }
+- if (is_shadow_pwd && ! spw_open (O_RDWR)) {
+- fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
+- exit (1);
+- }
+-#endif
++ if (is_shadow_pwd && ! spw_lock ()) {
++ fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
++ exit (1);
++ }
++ if (is_shadow_pwd && ! spw_open (O_RDWR)) {
++ fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
++ exit (1);
++ }
++#endif
++ if (! gr_lock ()) {
++ fprintf (stderr, "%s: unable to lock group file\n", Prog);
++ exit (E_LOCKING);
++ }
++ if (! gr_open (O_RDWR)) {
++ fprintf (stderr, "%s: unable to open group file\n", Prog);
++ fail_exit (10);
++ }
++#ifdef SHADOWGRP
++ if (is_shadow_grp && ! sgr_lock ()) {
++ fprintf (stderr, "%s: unable to lock shadow group file\n",
++ Prog);
++ fail_exit (E_LOCKING);
++ }
++ if (is_shadow_grp && ! sgr_open (O_RDWR)) {
++ fprintf (stderr, "%s: unable to open shadow group file\n",
++ Prog);
++ fail_exit (10);
++ }
++#endif /* SHADOWGRP*/
++
+ }
+
+
+@@ -1424,9 +1537,6 @@
+ struct spwd spent;
+ #endif
+
+- if (! oflg)
+- find_new_uid ();
+-
+ #ifdef AUTH_METHODS
+ if (Aflg) {
+ convert_auth(user_auth, auth_arg);
+@@ -1582,6 +1692,117 @@
+ }
+ }
+
++/* a fake something */
++static char *empty_list = NULL;
++
++/*
++ * new_grent - initialize the values in a group file entry
++ *
++ * new_grent() takes all of the values that have been entered and
++ * fills in a (struct group) with them.
++ */
++
++static void
++new_grent(grent)
++ struct group *grent;
++{
++ bzero ((char *) grent, sizeof *grent);
++ grent->gr_name = user_name;
++ grent->gr_passwd = "x";
++ grent->gr_gid = user_gid;
++ grent->gr_mem = &empty_list;
++}
++
++#ifdef SHADOWGRP
++/*
++ * new_sgent - initialize the values in a shadow group file entry
++ *
++ * new_sgent() takes all of the values that have been entered and
++ * fills in a (struct sgrp) with them.
++ */
++
++static void
++new_sgent(sgent)
++ struct sgrp *sgent;
++{
++ bzero ((char *) sgent, sizeof *sgent);
++ sgent->sg_name = user_name;
++ sgent->sg_passwd = "!";
++ sgent->sg_adm = &empty_list;
++ sgent->sg_mem = &empty_list;
++}
++#endif /* SHADOWGRP */
++
++/*
++ * grp_update - add new group file entries
++ *
++ * grp_update() writes the new records to the group files.
++ */
++
++static void grp_add()
++{
++ struct group grp;
++#ifdef SHADOWGRP
++ struct sgrp sgrp;
++#endif /* SHADOWGRP */
++
++ /*
++ * Create the initial entries for this new group.
++ */
++
++ new_grent (&grp);
++#ifdef SHADOWGRP
++ new_sgent (&sgrp);
++#endif /* SHADOWGRP */
++
++ /*
++ * Write out the new group file entry.
++ */
++
++ if (! gr_update (&grp)) {
++ fprintf (stderr, "%s: error adding new group entry\n", Prog);
++ fail_exit (10);
++ }
++#ifdef NDBM
++
++ /*
++ * Update the DBM group file with the new entry as well.
++ */
++
++ if (gr_dbm_present() && ! gr_dbm_update (&grp)) {
++ fprintf (stderr, "%s: cannot add new dbm group entry\n", Prog);
++ fail_exit (10);
++ }
++ endgrent ();
++#endif /* NDBM */
++
++#ifdef SHADOWGRP
++
++ /*
++ * Write out the new shadow group entries as well.
++ */
++
++ if (is_shadow_grp && ! sgr_update (&sgrp)) {
++ fprintf (stderr, "%s: error adding new group entry\n", Prog);
++ fail_exit (10);
++ }
++#ifdef NDBM
++
++ /*
++ * Update the DBM group file with the new entry as well.
++ */
++
++ if (is_shadow_grp && sg_dbm_present() && ! sg_dbm_update (&sgrp)) {
++ fprintf (stderr, "%s: cannot add new dbm group entry\n", Prog);
++ fail_exit (10);
++ }
++ endsgent ();
++#endif /* NDBM */
++#endif /* SHADOWGRP */
++ SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n",
++ user_name, user_gid));
++}
++
+ /*
+ * main - useradd command
+ */
+@@ -1591,76 +1812,100 @@
+ int argc;
+ char **argv;
+ {
+- /*
+- * Get my name so that I can use it to report errors.
+- */
++ /*
++ * Get my name so that I can use it to report errors.
++ */
+
+- Prog = Basename(argv[0]);
++ Prog = Basename(argv[0]);
+
+- openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
++ openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
+
+ #ifdef SHADOWPWD
+- is_shadow_pwd = (access(SHADOW_FILE, 0) == 0);
++ is_shadow_pwd = (access(SHADOW_FILE, 0) == 0);
+ #endif
+ #ifdef SHADOWGRP
+- is_shadow_grp = (access(SGROUP_FILE, 0) == 0);
++ is_shadow_grp = (access(SGROUP_FILE, 0) == 0);
+ #endif
+
+- /*
+- * The open routines for the NDBM files don't use read-write
+- * as the mode, so we have to clue them in.
+- */
++ /*
++ * The open routines for the NDBM files don't use read-write
++ * as the mode, so we have to clue them in.
++ */
+
+ #ifdef NDBM
+- pw_dbm_mode = O_RDWR;
++ pw_dbm_mode = O_RDWR;
+ #ifdef SHADOWPWD
+- sp_dbm_mode = O_RDWR;
++ sp_dbm_mode = O_RDWR;
+ #endif
+- gr_dbm_mode = O_RDWR;
++ gr_dbm_mode = O_RDWR;
+ #ifdef SHADOWGRP
+- sg_dbm_mode = O_RDWR;
++ sg_dbm_mode = O_RDWR;
+ #endif
+ #endif
+- get_defaults();
++ get_defaults();
+
+- process_flags(argc, argv);
++ process_flags(argc, argv);
+
+- /*
+- * See if we are messing with the defaults file, or creating
+- * a new user.
+- */
++ if (!rflg) /* for system accounts defaults are ignored
++ * == do not create */
++ if (getdef_bool("CREATE_HOME"))
++ mflg = 1;
+
+- if (Dflg) {
+- if (gflg || bflg || fflg || eflg || sflg)
+- exit (set_defaults () ? 1:0);
++ if (Mflg) /* absolutely sure that we do not create home dirs */
++ mflg = 0;
++ /*
++ * See if we are messing with the defaults file, or creating
++ * a new user.
++ */
+
+- show_defaults ();
+- exit (0);
+- }
++ if (Dflg) {
++ if (gflg || bflg || fflg || eflg || sflg)
++ exit (set_defaults () ? 1:0);
+
+- /*
+- * Start with a quick check to see if the user exists.
+- */
++ show_defaults ();
++ exit (0);
++ }
+
+- if (getpwnam(user_name)) {
+- fprintf(stderr, "%s: user %s exists\n", Prog, user_name);
+- exit(E_NAME_IN_USE);
+- }
++ /*
++ * Start with a quick check to see if the user exists.
++ */
+
+- /*
+- * Do the hard stuff - open the files, create the user entries,
+- * create the home directory, then close and update the files.
+- */
+-
+- open_files ();
++ if (getpwnam(user_name)) {
++ if (!oflg) {
++ fprintf(stderr, "%s: user %s exists\n", Prog, user_name);
++ exit(E_NAME_IN_USE);
++ } else {
++ exit (E_SUCCESS);
++ }
++ }
+
+- usr_update ();
++ /*
++ * Do the hard stuff - open the files, create the user entries,
++ * create the home directory, then close and update the files.
++ */
++
++ open_files ();
++
++ /* first, seek for a valid uid to use for this user.
++ * We do this because later we can use the uid we found as
++ * gid too ... --rh */
++ if (! uflg)
++ find_new_uid ();
++
++ /* do we have to add a group for that user ? */
++ if (! (nflg || gflg)) {
++ find_new_gid();
++ grp_add();
++ }
++
++ usr_update ();
++
++ if (mflg) {
++ create_home ();
++ copy_tree (def_template, user_home, user_id, user_gid);
++ }
++ close_files ();
+
+- if (mflg) {
+- create_home ();
+- copy_tree (def_template, user_home, user_id, user_gid);
+- }
+- close_files ();
+- exit(E_SUCCESS);
+- /*NOTREACHED*/
++ exit(E_SUCCESS);
++ /*NOTREACHED*/
+ }
+--- shadow-970616/src/groupadd.c.rh Thu May 1 19:07:11 1997
++++ shadow-970616/src/groupadd.c Fri Dec 12 15:36:29 1997
+@@ -61,6 +61,11 @@
+ oflg = 0, /* permit non-unique group ID to be specified with -g */
+ gflg = 0; /* ID value for the new group */
+
++/* For adding "system" accounts */
++static int system_flag = 0;
++static int force_flag = 0;
++#define MIN_GID 10
++
+ #ifdef NDBM
+ extern int gr_dbm_mode;
+ extern int sg_dbm_mode;
+@@ -75,7 +80,7 @@
+ static void
+ usage()
+ {
+- fprintf (stderr, "usage: groupadd [-g gid [-o]] group\n");
++ fprintf (stderr, "usage: groupadd [-g gid [-o]] [-r] [-f] group\n");
+ exit (2);
+ }
+
+@@ -202,8 +207,13 @@
+ const struct group *grp;
+ gid_t gid_min, gid_max;
+
+- gid_min = getdef_num("GID_MIN", 100);
+- gid_max = getdef_num("GID_MAX", 60000);
++ if (!system_flag) {
++ gid_min = getdef_num("GID_MIN", 500);
++ gid_max = getdef_num("GID_MAX", 60000);
++ } else {
++ gid_min = MIN_GID;
++ gid_max = getdef_num("GID_MIN", 499);
++ }
+
+ /*
+ * Start with some GID value if the user didn't provide us with
+@@ -227,16 +237,34 @@
+ while ((grp = getgrent())) {
+ #endif
+ if (strcmp(group_name, grp->gr_name) == 0) {
++ if (!force_flag) {
+ fprintf(stderr, "%s: name %s is not unique\n",
+ Prog, group_name);
+ fail_exit(9);
++ } else {
++ fail_exit(0);
++ }
+ }
+ if (gflg && group_id == grp->gr_gid) {
++ if (!force_flag) {
+ fprintf(stderr, "%s: gid %ld is not unique\n",
+ Prog, (long) group_id);
+ fail_exit(4);
++ } else {
++ /* we invalidate the gflg and search again */
++ gflg = 0;
++ if (oflg)
++ oflg = 0;
++ /* now, start at the begining... */
++#ifdef NO_GETGRENT
++ gr_rewind();
++#else
++ setgrent();
++#endif
++ continue;
++ }
+ }
+- if (! gflg && grp->gr_gid >= group_id) {
++ if (!gflg && grp->gr_gid >= group_id) {
+ if (grp->gr_gid > gid_max)
+ continue;
+ group_id = grp->gr_gid + 1;
+@@ -298,42 +326,49 @@
+ process_flags(argc, argv)
+ int argc;
+ char **argv;
+-{
+- extern int optind;
+- extern char *optarg;
+- char *end;
+- int arg;
++ {
++ extern int optind;
++ extern char *optarg;
++ char *end;
++ int arg;
+
+- while ((arg = getopt (argc, argv, "og:")) != EOF) {
++ while ((arg = getopt (argc, argv, "og:rf")) != EOF) {
+ switch (arg) {
+- case 'g':
+- gflg++;
+- if (! isdigit (optarg[0]))
+- usage ();
+-
+- group_id = strtol (optarg, &end, 10);
+- if (*end != '\0') {
+- fprintf (stderr, "%s: invalid group %s\n",
+- Prog, optarg);
+- fail_exit (3);
+- }
+- break;
+- case 'o':
+- if (! gflg)
+- usage ();
+-
+- oflg++;
+- break;
+- default:
+- usage ();
++ case 'g':
++ gflg++;
++ if (! isdigit (optarg[0]))
++ usage ();
++
++ group_id = strtol (optarg, &end, 10);
++ if (*end != '\0') {
++ fprintf (stderr, "%s: invalid group %s\n",
++ Prog, optarg);
++ fail_exit (3);
++ }
++ break;
++ case 'o':
++ if (! gflg)
++ usage ();
++
++ oflg++;
++ break;
++ case 'r': /* "system" group */
++ system_flag++;
++ break;
++ case 'f': /* "force" - don't exit with error if group already exist */
++ force_flag++;
++ break;
++
++ default:
++ usage ();
+ }
+- }
+- if (optind != argc - 1)
++ }
++ if (optind != argc - 1)
+ usage ();
+
+- group_name = argv[argc - 1];
+- check_new_name ();
+-}
++ group_name = argv[argc - 1];
++ check_new_name ();
++ }
+
+ /*
+ * close_files - close all of the files that were opened
+@@ -448,8 +483,12 @@
+ */
+
+ if (getgrnam(group_name)) {
++ if ( !force_flag) {
+ fprintf (stderr, "%s: group %s exists\n", Prog, group_name);
+ exit(9);
++ } else {
++ exit(0);
++ }
+ }
+
+ /*
diff --git a/current/redhat/shadow-970616-utuser.patch b/current/redhat/shadow-970616-utuser.patch
new file mode 100644
index 00000000..2c27cb25
--- /dev/null
+++ b/current/redhat/shadow-970616-utuser.patch
@@ -0,0 +1,12 @@
+--- shadow-970616/configure.in.ewt Thu Nov 13 16:43:25 1997
++++ shadow-970616/configure.in Thu Nov 13 16:43:34 1997
+@@ -38,7 +38,8 @@
+ AC_CHECK_HEADERS(gshadow.h shadow.h lastlog.h)
+
+ AC_EGREP_HEADER(ut_host, utmp.h, AC_DEFINE(UT_HOST))
+-AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_name))
++AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_user),
++ AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_name)))
+ AC_EGREP_HEADER(ll_host, lastlog.h, AC_DEFINE(HAVE_LL_HOST))
+
+ dnl Checks for typedefs, structures, and compiler characteristics.
diff --git a/current/redhat/shadow-970616.login.defs b/current/redhat/shadow-970616.login.defs
new file mode 100644
index 00000000..6f578df7
--- /dev/null
+++ b/current/redhat/shadow-970616.login.defs
@@ -0,0 +1,57 @@
+# *REQUIRED*
+# Directory where mailboxes reside, _or_ name of file, relative to the
+# home directory. If you _do_ define both, MAIL_DIR takes precedence.
+# QMAIL_DIR is for Qmail
+#
+#QMAIL_DIR Maildir
+MAIL_DIR /var/spool/mail
+#MAIL_FILE .mail
+
+# Password aging controls:
+#
+# PASS_MAX_DAYS Maximum number of days a password may be used.
+# PASS_MIN_DAYS Minimum number of days allowed between password changes.
+# PASS_MIN_LEN Minimum acceptable password length.
+# PASS_WARN_AGE Number of days warning given before a password expires.
+#
+PASS_MAX_DAYS 99999
+PASS_MIN_DAYS 0
+PASS_MIN_LEN 5
+PASS_WARN_AGE 7
+
+#
+# Min/max values for automatic uid selection in useradd
+#
+UID_MIN 500
+UID_MAX 60000
+
+#
+# Min/max values for automatic gid selection in groupadd
+#
+GID_MIN 500
+GID_MAX 60000
+
+#
+# Require password before chfn/chsh can make any changes.
+#
+CHFN_AUTH yes
+
+#
+# Don't allow users to change their "real name" using chfn.
+#
+CHFN_RESTRICT yes
+
+#
+# If defined, this command is run when removing a user.
+# It should remove any at/cron/print jobs etc. owned by
+# the user to be removed (passed as the first argument).
+#
+#USERDEL_CMD /usr/sbin/userdel_local
+
+#
+# If useradd should create home directories for users by default
+# On RH systems, we do. This option is ORed with the -m flag on
+# useradd command line.
+#
+CREATE_HOME yes
+
diff --git a/current/redhat/shadow-970616.useradd b/current/redhat/shadow-970616.useradd
new file mode 100644
index 00000000..ae81dbb3
--- /dev/null
+++ b/current/redhat/shadow-970616.useradd
@@ -0,0 +1,7 @@
+# useradd defaults file
+GROUP=100
+HOME=/home
+INACTIVE=-1
+EXPIRE=
+SHELL=/bin/bash
+SKEL=/etc/skel
diff --git a/current/redhat/shadow-utils-970616.spec b/current/redhat/shadow-utils-970616.spec
new file mode 100644
index 00000000..4fc4dc1c
--- /dev/null
+++ b/current/redhat/shadow-utils-970616.spec
@@ -0,0 +1,137 @@
+Summary: Shadow password file utilities for Linux
+Name: shadow-utils
+Version: 970616
+Release: 11
+Source0: ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/beta/shadow-970616.tar.gz
+Source1: shadow-970616.login.defs
+Source2: shadow-970616.useradd
+Patch0: shadow-970616-rh.patch
+Patch1: shadow-970616-utuser.patch
+Patch2: shadow-970616-glibc.patch
+Patch3: shadow-970616-fix.patch
+Copyright: BSD
+Group: Utilities/System
+BuildRoot: /var/tmp/shadow-utils
+Obsoletes: adduser
+
+%changelog
+* Tue Dec 30 1997 Cristian Gafton <gafton@redhat.com>
+- updated the spec file
+- updated the patch so that new accounts created on shadowed system won't
+ confuse pam_pwdb anymore ('!!' default password instead on '!')
+- fixed a bug that made useradd -G segfault
+- the check for the ut_user is now patched into configure
+
+* Thu Nov 13 1997 Erik Troan <ewt@redhat.com>
+- added patch for XOPEN oddities in glibc headers
+- check for ut_user before checking for ut_name -- this works around some
+ confusion on glibc 2.1 due to the utmpx header not defining the ut_name
+ compatibility stuff. I used a gross sed hack here because I couldn't make
+ automake work properly on the sparc (this could be a glibc 2.0.99 problem
+ though). The utuser patch works fine, but I don't apply it.
+- sleep after running autoconf
+
+* Thu Nov 06 1997 Cristian Gafton <gafton@redhat.com>
+- added forgot lastlog command to the spec file
+
+* Mon Oct 26 1997 Cristian Gafton <gafton@redhat.com>
+- obsoletes adduser
+
+* Thu Oct 23 1997 Cristian Gafton <gafton@redhat.com>
+- modified groupadd; updated the patch
+
+* Fri Sep 12 1997 Cristian Gafton <gafton@redhat.com>
+- updated to 970616
+- changed useradd to meet RH specs
+- fixed some bugs
+
+* Tue Jun 17 1997 Erik Troan <ewt@redhat.com>
+- built against glibc
+
+%description
+This package includes the programs necessary to convert standard
+UNIX password files to the shadow password format, as well as
+programs for command-line management of the user's accounts.
+ - 'pwconv' converts everything to the shadow password format.
+ - 'pwunconv' unconverts from shadow passwords, generating a file
+ in the current directory called npasswd that is a standard UNIX
+ password file.
+ - 'pwck' checks the integrity of the password and shadow files.
+ - 'lastlog' prints out the last login times of all users.
+ - 'useradd', 'userdel' and 'usermod' for accounts management.
+ - 'groupadd', 'groupdel' and 'groupmod' for group management.
+
+A number of man pages are also included that relate to these utilities,
+and shadow passwords in general.
+
+%prep
+# This is just a few of the core utilities from the shadow suite...
+# packaged up for use w/PAM
+%setup -n shadow-970616
+%patch -p1 -b .rh
+#%patch1 -p1 -b .utname
+%patch2 -p1 -b .xopen
+%patch3 -p1 -b .fix
+
+%build
+autoheader
+autoconf
+sleep 2
+CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/usr
+make install prefix=/$RPM_BUILD_ROOT/usr
+mkdir -p $RPM_BUILD_ROOT/etc/default
+install -m 0600 -o root $RPM_SOURCE_DIR/shadow-970616.useradd $RPM_BUILD_ROOT/etc/default/useradd
+install -m 0644 -o root $RPM_SOURCE_DIR/shadow-970616.login.defs $RPM_BUILD_ROOT/etc/login.defs
+install -m 0500 -o root src/pwconv $RPM_BUILD_ROOT/usr/sbin
+install -m 0500 -o root src/pwunconv $RPM_BUILD_ROOT/usr/sbin
+ln -s pwconv $RPM_BUILD_ROOT/usr/sbin/pwconv5
+install -m 0644 -o root man/pw*conv.8 $RPM_BUILD_ROOT/usr/man/man8
+ln -s pwconv.8 $RPM_BUILD_ROOT/usr/man/man8/pwconv5.8
+ln -s useradd $RPM_BUILD_ROOT/usr/sbin/adduser
+ln -s useradd.8 $RPM_BUILD_ROOT/usr/man/man8/adduser.8
+
+%files
+%doc doc/ANNOUNCE doc/CHANGES doc/HOWTO
+%doc doc/LICENSE doc/README doc/README.linux
+%dir /etc/default
+/usr/sbin/adduser
+/usr/sbin/useradd
+/usr/sbin/usermod
+/usr/sbin/userdel
+/usr/sbin/groupadd
+/usr/sbin/groupdel
+/usr/sbin/groupmod
+/usr/sbin/grpck
+/usr/sbin/pwck
+/usr/bin/chage
+/usr/bin/gpasswd
+/usr/sbin/lastlog
+# /usr/sbin/vipw
+/usr/sbin/chpasswd
+/usr/sbin/newusers
+/usr/sbin/pw*conv*
+/usr/man/man1/chage.1
+/usr/man/man1/gpasswd.1
+/usr/man/man3/shadow.3
+/usr/man/man5/shadow.5
+/usr/man/man8/adduser.8
+/usr/man/man8/chpasswd.8
+/usr/man/man8/group*.8
+/usr/man/man8/user*.8
+/usr/man/man8/pwck.8
+/usr/man/man8/grpck.8
+/usr/man/man8/newusers.8
+# /usr/man/man8/shadowconfig.8
+/usr/man/man8/pw*conv*.8
+# /usr/man/man8/vipw.8
+/usr/man/man8/lastlog.8
+%config /etc/login.defs
+%config /etc/default/useradd
+
+%clean
+rm -rf $RPM_BUILD_ROOT
diff --git a/current/redhat/shadow-utils.spec.in b/current/redhat/shadow-utils.spec.in
new file mode 100644
index 00000000..017100bf
--- /dev/null
+++ b/current/redhat/shadow-utils.spec.in
@@ -0,0 +1,154 @@
+# shadow-utils.spec generated automatically from shadow-utils.spec.in
+# $Id: shadow-utils.spec.in,v 1.3 2000/09/02 18:40:43 marekm Exp $
+
+# FIXME - this is out of date, please update for current Red Hat
+
+Summary: Shadow password file utilities for Linux
+Name: shadow-utils
+Version: @VERSION@
+Release: 1
+Copyright: Free
+Group: Utilities/System
+Source: ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/shadow-@VERSION@.tar.gz
+BuildRoot: /var/tmp/shadow-utils
+Packager: Timo Karjalainen <timok@iki.fi>
+# Obsoletes: adduser
+
+%description
+This package includes the programs necessary to convert traditional
+V7 UNIX password files to the SVR4 shadow password format and additional
+tools to work with shadow passwords.
+ - 'pwconv' converts everything to the shadow password format.
+ - 'pwunconv' converts back to non-shadow passwords.
+ - 'pwck' checks the integrity of the password and shadow files.
+ - 'lastlog' prints out the last login times of all users.
+ - 'useradd', 'userdel', 'usermod' to manage user accounts.
+ - 'groupadd', 'groupdel', 'groupmod' to manage groups.
+
+A number of man pages are also included that relate to these utilities,
+and shadow passwords in general.
+
+%changelog
+
+* Sun Dec 14 1997 Marek Michalkiewicz <marekm@piast.t19.ds.pwr.wroc.pl>
+
+- Lots of changes, see doc/CHANGES for more details
+
+* Sun Jun 08 1997 Timo Karjalainen <timok@iki.fi>
+
+- Initial release
+
+%prep
+# This is just a few of the core utilities from the shadow suite...
+# packaged up for use w/PAM
+%setup -n shadow-@VERSION@
+
+%build
+# shared lib support is untested, so...
+CFLAGS="$RPM_OPT_FLAGS" ./configure --disable-shared --prefix=/usr --exec-prefix=/usr
+make
+
+%install
+if [ -d $RPM_BUILD_ROOT ] ; then
+ rm -rf $RPM_BUILD_ROOT
+fi
+mkdir -p $RPM_BUILD_ROOT/usr
+# neato trick, heh ? :-)
+./configure --prefix=$RPM_BUILD_ROOT/usr
+make install
+mkdir -p $RPM_BUILD_ROOT/etc/default
+
+# FIXME
+#install -m 0600 -o root $RPM_SOURCE_DIR/shadow-970616.useradd $RPM_BUILD_ROOT/etc/default/useradd
+#install -m 0644 -o root $RPM_SOURCE_DIR/shadow-970616.login.defs $RPM_BUILD_ROOT/etc/login.defs
+#ln -s useradd $RPM_BUILD_ROOT/usr/sbin/adduser
+#ln -s useradd.8 $RPM_BUILD_ROOT/usr/man/man8/adduser.8
+
+#make prefix=$RPM_BUILD_ROOT/usr exec_prefix=$RPM_BUILD_ROOT/usr install
+#touch $RPM_BUILD_ROOT/etc/{login.defs,default/useradd}
+#chmod 640 $RPM_BUILD_ROOT/etc/{login.defs,default/useradd}
+#chown root $RPM_BUILD_ROOT/etc/{login.defs,default/useradd}
+#chgrp root $RPM_BUILD_ROOT/etc/{login.defs,default/useradd}
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%doc doc/ANNOUNCE doc/CHANGES doc/HOWTO
+%doc doc/LICENSE doc/README doc/README.linux
+%dir /etc/default
+%config /etc/default/useradd
+# %config /etc/limits
+# %config /etc/login.access
+%config /etc/login.defs
+# %config /etc/limits
+# %config /etc/porttime
+# %config /etc/securetty
+# %config /etc/shells
+# %config /etc/suauth
+# /bin/login
+# /bin/su
+/usr/bin/chage
+# /usr/bin/chfn
+# /usr/bin/chsh
+# /usr/bin/expiry
+# /usr/bin/faillog
+/usr/bin/gpasswd
+/usr/bin/lastlog
+# /usr/bin/newgrp
+# /usr/bin/passwd
+# /usr/bin/sg
+/usr/man/man1/chage.1
+# /usr/man/man1/chfn.1
+# /usr/man/man1/chsh.1
+/usr/man/man1/gpasswd.1
+# /usr/man/man1/login.1
+# /usr/man/man1/passwd.1
+# /usr/man/man1/sg.1
+# /usr/man/man1/su.1
+/usr/man/man3/shadow.3
+# /usr/man/man5/faillog.5
+# /usr/man/man5/limits.5
+# /usr/man/man5/login.access.5
+# /usr/man/man5/login.defs.5
+# /usr/man/man5/passwd.5
+# /usr/man/man5/porttime.5
+/usr/man/man5/shadow.5
+# /usr/man/man5/suauth.5
+# /usr/man/man8/adduser.8
+/usr/man/man8/chpasswd.8
+# /usr/man/man8/faillog.8
+/usr/man/man8/groupadd.8
+/usr/man/man8/groupdel.8
+/usr/man/man8/groupmod.8
+/usr/man/man8/grpck.8
+/usr/man/man8/lastlog.8
+# /usr/man/man8/logoutd.8
+/usr/man/man8/newusers.8
+/usr/man/man8/pwck.8
+/usr/man/man8/pwconv.8
+# /usr/man/man8/shadowconfig.8
+/usr/man/man8/useradd.8
+/usr/man/man8/userdel.8
+/usr/man/man8/usermod.8
+# /usr/man/man8/vigr.8
+# /usr/man/man8/vipw.8
+# /usr/sbin/adduser
+/usr/sbin/chpasswd
+/usr/sbin/groupadd
+/usr/sbin/groupdel
+/usr/sbin/groupmod
+/usr/sbin/grpck
+/usr/sbin/grpconv
+/usr/sbin/grpunconv
+# /usr/sbin/logoutd
+/usr/sbin/newusers
+/usr/sbin/pwck
+/usr/sbin/pwconv
+/usr/sbin/pwunconv
+# /usr/sbin/shadowconfig
+/usr/sbin/useradd
+/usr/sbin/userdel
+/usr/sbin/usermod
+# /usr/sbin/vigr
+# /usr/sbin/vipw
diff --git a/current/src/Makefile.am b/current/src/Makefile.am
new file mode 100644
index 00000000..db8203fd
--- /dev/null
+++ b/current/src/Makefile.am
@@ -0,0 +1,90 @@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+# Watch out; note the difference between prefix & exec_prefix.
+# Normally configure sets exec_prefix to root when prefix is /usr.
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+ubindir = ${prefix}/bin
+usbindir = ${prefix}/sbin
+localedir = $(datadir)/locale
+
+noinst_HEADERS = patchlevel.h
+
+DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
+
+# XXX why are login and su in /bin anyway (other than for
+# historical reasons)?
+#
+# if the system is screwed so badly that it can't mount /usr,
+# you can (hopefully) boot single user, and then you're root
+# so you don't need these programs for recovery.
+#
+# also /lib/libshadow.so.x.xx (if any) could be moved to /usr/lib
+# and installation would be much simpler (just two directories,
+# $prefix/bin and $prefix/sbin, no install-data hacks...)
+
+bin_PROGRAMS = login \
+ su
+ubin_PROGRAMS = faillog lastlog \
+ chage chfn chsh expiry gpasswd newgrp passwd
+usbin_PROGRAMS = chpasswd dpasswd groupadd groupdel groupmod \
+ logoutd mkpasswd newusers \
+ useradd userdel usermod grpck pwck vipw \
+ grpconv grpunconv pwconv pwunconv
+
+EXTRA_DIST = shadowconfig.sh
+
+# id and groups are from gnu, sulogin from sysvinit,
+# also suid programs are installed by hand.
+# XXX installation by hand breaks libtool shared lib support
+# (the wrapper scripts get installed instead of binaries),
+# so we now chmod the programs by hand after normal installation.
+
+suidbins = su
+suidubins = chage chfn chsh expiry gpasswd newgrp passwd
+
+install-exec-hook:
+ for i in $(suidbins); do \
+ chmod 4755 $(DESTDIR)$(bindir)/$$i; \
+ done
+
+install-data-hook:
+ for i in $(suidubins); do \
+ chmod 4755 $(DESTDIR)$(ubindir)/$$i; \
+ done
+ rm -f $(DESTDIR)$(ubindir)/sg
+ ln -s newgrp $(DESTDIR)$(ubindir)/sg
+
+noinst_PROGRAMS = groups id sulogin
+
+#install-exec-local:
+# $(mkinstalldirs) $(bindir)
+# for i in $(suidbins); do \
+# $(INSTALL) -m 4755 $$i $(bindir); \
+# done
+# $(mkinstalldirs) $(ubindir)
+# for i in $(suidubins); do \
+# $(INSTALL) -m 4755 $$i $(ubindir); \
+# done
+# rm -f $(bindir)/sg
+# ln -s $(ubindir)/newgrp $(bindir)/sg
+#
+#noinst_PROGRAMS = id groups \
+# su \
+# chage chfn chsh expiry gpasswd newgrp passwd \
+# sulogin
+
+shlibs = ../lib/libshadow.la
+# With glibc2, almost all programs need libcrypt for some reason,
+# even those that don't actually use crypt().
+LDADD = ${shlibs} ../libmisc/libmisc.a ../lib/libshadow.a @INTLLIBS@ @LIBCRYPT@ @LIBTCFS@ @LIBSKEY@ @LIBMD@
+INCLUDES = -I${top_srcdir}/lib -I$(top_srcdir)/libmisc
+
+chfn_LDADD = ${LDADD} @LIBPAM@
+chsh_LDADD = ${LDADD} @LIBPAM@
+login_LDADD = ${LDADD} @LIBPAM@
+passwd_LDADD = ${LDADD} @LIBCRACK@ @LIBPAM@
+su_LDADD = ${LDADD} @LIBPAM@
+
diff --git a/current/src/Makefile.in b/current/src/Makefile.in
new file mode 100644
index 00000000..773a3b3c
--- /dev/null
+++ b/current/src/Makefile.in
@@ -0,0 +1,895 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBMD = @LIBMD@
+LIBPAM = @LIBPAM@
+LIBSKEY = @LIBSKEY@
+LIBTCFS = @LIBTCFS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+l = @l@
+
+AUTOMAKE_OPTIONS = 1.0 foreign
+
+# Watch out; note the difference between prefix & exec_prefix.
+# Normally configure sets exec_prefix to root when prefix is /usr.
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+ubindir = ${prefix}/bin
+usbindir = ${prefix}/sbin
+localedir = $(datadir)/locale
+
+noinst_HEADERS = patchlevel.h
+
+DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
+
+# XXX why are login and su in /bin anyway (other than for
+# historical reasons)?
+#
+# if the system is screwed so badly that it can't mount /usr,
+# you can (hopefully) boot single user, and then you're root
+# so you don't need these programs for recovery.
+#
+# also /lib/libshadow.so.x.xx (if any) could be moved to /usr/lib
+# and installation would be much simpler (just two directories,
+# $prefix/bin and $prefix/sbin, no install-data hacks...)
+
+bin_PROGRAMS = login su
+
+ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
+
+usbin_PROGRAMS = chpasswd dpasswd groupadd groupdel groupmod logoutd mkpasswd newusers useradd userdel usermod grpck pwck vipw grpconv grpunconv pwconv pwunconv
+
+
+EXTRA_DIST = shadowconfig.sh
+
+# id and groups are from gnu, sulogin from sysvinit,
+# also suid programs are installed by hand.
+# XXX installation by hand breaks libtool shared lib support
+# (the wrapper scripts get installed instead of binaries),
+# so we now chmod the programs by hand after normal installation.
+
+suidbins = su
+suidubins = chage chfn chsh expiry gpasswd newgrp passwd
+
+noinst_PROGRAMS = groups id sulogin
+
+#install-exec-local:
+# $(mkinstalldirs) $(bindir)
+# for i in $(suidbins); do \
+# $(INSTALL) -m 4755 $$i $(bindir); \
+# done
+# $(mkinstalldirs) $(ubindir)
+# for i in $(suidubins); do \
+# $(INSTALL) -m 4755 $$i $(ubindir); \
+# done
+# rm -f $(bindir)/sg
+# ln -s $(ubindir)/newgrp $(bindir)/sg
+#
+#noinst_PROGRAMS = id groups \
+# su \
+# chage chfn chsh expiry gpasswd newgrp passwd \
+# sulogin
+
+shlibs = ../lib/libshadow.la
+# With glibc2, almost all programs need libcrypt for some reason,
+# even those that don't actually use crypt().
+LDADD = ${shlibs} ../libmisc/libmisc.a ../lib/libshadow.a @INTLLIBS@ @LIBCRYPT@ @LIBTCFS@ @LIBSKEY@ @LIBMD@
+INCLUDES = -I${top_srcdir}/lib -I$(top_srcdir)/libmisc
+
+chfn_LDADD = ${LDADD} @LIBPAM@
+chsh_LDADD = ${LDADD} @LIBPAM@
+login_LDADD = ${LDADD} @LIBPAM@
+passwd_LDADD = ${LDADD} @LIBCRACK@ @LIBPAM@
+su_LDADD = ${LDADD} @LIBPAM@
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(ubin_PROGRAMS) \
+$(usbin_PROGRAMS)
+
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+login_SOURCES = login.c
+login_OBJECTS = login.o
+login_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+login_LDFLAGS =
+su_SOURCES = su.c
+su_OBJECTS = su.o
+su_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+su_LDFLAGS =
+groups_SOURCES = groups.c
+groups_OBJECTS = groups.o
+groups_LDADD = $(LDADD)
+groups_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+groups_LDFLAGS =
+id_SOURCES = id.c
+id_OBJECTS = id.o
+id_LDADD = $(LDADD)
+id_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+id_LDFLAGS =
+sulogin_SOURCES = sulogin.c
+sulogin_OBJECTS = sulogin.o
+sulogin_LDADD = $(LDADD)
+sulogin_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+sulogin_LDFLAGS =
+faillog_SOURCES = faillog.c
+faillog_OBJECTS = faillog.o
+faillog_LDADD = $(LDADD)
+faillog_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+faillog_LDFLAGS =
+lastlog_SOURCES = lastlog.c
+lastlog_OBJECTS = lastlog.o
+lastlog_LDADD = $(LDADD)
+lastlog_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+lastlog_LDFLAGS =
+chage_SOURCES = chage.c
+chage_OBJECTS = chage.o
+chage_LDADD = $(LDADD)
+chage_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+chage_LDFLAGS =
+chfn_SOURCES = chfn.c
+chfn_OBJECTS = chfn.o
+chfn_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+chfn_LDFLAGS =
+chsh_SOURCES = chsh.c
+chsh_OBJECTS = chsh.o
+chsh_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+chsh_LDFLAGS =
+expiry_SOURCES = expiry.c
+expiry_OBJECTS = expiry.o
+expiry_LDADD = $(LDADD)
+expiry_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+expiry_LDFLAGS =
+gpasswd_SOURCES = gpasswd.c
+gpasswd_OBJECTS = gpasswd.o
+gpasswd_LDADD = $(LDADD)
+gpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+gpasswd_LDFLAGS =
+newgrp_SOURCES = newgrp.c
+newgrp_OBJECTS = newgrp.o
+newgrp_LDADD = $(LDADD)
+newgrp_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+newgrp_LDFLAGS =
+passwd_SOURCES = passwd.c
+passwd_OBJECTS = passwd.o
+passwd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+passwd_LDFLAGS =
+chpasswd_SOURCES = chpasswd.c
+chpasswd_OBJECTS = chpasswd.o
+chpasswd_LDADD = $(LDADD)
+chpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+chpasswd_LDFLAGS =
+dpasswd_SOURCES = dpasswd.c
+dpasswd_OBJECTS = dpasswd.o
+dpasswd_LDADD = $(LDADD)
+dpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+dpasswd_LDFLAGS =
+groupadd_SOURCES = groupadd.c
+groupadd_OBJECTS = groupadd.o
+groupadd_LDADD = $(LDADD)
+groupadd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+groupadd_LDFLAGS =
+groupdel_SOURCES = groupdel.c
+groupdel_OBJECTS = groupdel.o
+groupdel_LDADD = $(LDADD)
+groupdel_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+groupdel_LDFLAGS =
+groupmod_SOURCES = groupmod.c
+groupmod_OBJECTS = groupmod.o
+groupmod_LDADD = $(LDADD)
+groupmod_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+groupmod_LDFLAGS =
+logoutd_SOURCES = logoutd.c
+logoutd_OBJECTS = logoutd.o
+logoutd_LDADD = $(LDADD)
+logoutd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+logoutd_LDFLAGS =
+mkpasswd_SOURCES = mkpasswd.c
+mkpasswd_OBJECTS = mkpasswd.o
+mkpasswd_LDADD = $(LDADD)
+mkpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+mkpasswd_LDFLAGS =
+newusers_SOURCES = newusers.c
+newusers_OBJECTS = newusers.o
+newusers_LDADD = $(LDADD)
+newusers_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+newusers_LDFLAGS =
+useradd_SOURCES = useradd.c
+useradd_OBJECTS = useradd.o
+useradd_LDADD = $(LDADD)
+useradd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+useradd_LDFLAGS =
+userdel_SOURCES = userdel.c
+userdel_OBJECTS = userdel.o
+userdel_LDADD = $(LDADD)
+userdel_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+userdel_LDFLAGS =
+usermod_SOURCES = usermod.c
+usermod_OBJECTS = usermod.o
+usermod_LDADD = $(LDADD)
+usermod_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+usermod_LDFLAGS =
+grpck_SOURCES = grpck.c
+grpck_OBJECTS = grpck.o
+grpck_LDADD = $(LDADD)
+grpck_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+grpck_LDFLAGS =
+pwck_SOURCES = pwck.c
+pwck_OBJECTS = pwck.o
+pwck_LDADD = $(LDADD)
+pwck_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+pwck_LDFLAGS =
+vipw_SOURCES = vipw.c
+vipw_OBJECTS = vipw.o
+vipw_LDADD = $(LDADD)
+vipw_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+vipw_LDFLAGS =
+grpconv_SOURCES = grpconv.c
+grpconv_OBJECTS = grpconv.o
+grpconv_LDADD = $(LDADD)
+grpconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+grpconv_LDFLAGS =
+grpunconv_SOURCES = grpunconv.c
+grpunconv_OBJECTS = grpunconv.o
+grpunconv_LDADD = $(LDADD)
+grpunconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+grpunconv_LDFLAGS =
+pwconv_SOURCES = pwconv.c
+pwconv_OBJECTS = pwconv.o
+pwconv_LDADD = $(LDADD)
+pwconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+pwconv_LDFLAGS =
+pwunconv_SOURCES = pwunconv.c
+pwunconv_OBJECTS = pwunconv.o
+pwunconv_LDADD = $(LDADD)
+pwunconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \
+../lib/libshadow.a
+pwunconv_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = login.c su.c groups.c id.c sulogin.c faillog.c lastlog.c chage.c chfn.c chsh.c expiry.c gpasswd.c newgrp.c passwd.c chpasswd.c dpasswd.c groupadd.c groupdel.c groupmod.c logoutd.c mkpasswd.c newusers.c useradd.c userdel.c usermod.c grpck.c pwck.c vipw.c grpconv.c grpunconv.c pwconv.c pwunconv.c
+OBJECTS = login.o su.o groups.o id.o sulogin.o faillog.o lastlog.o chage.o chfn.o chsh.o expiry.o gpasswd.o newgrp.o passwd.o chpasswd.o dpasswd.o groupadd.o groupdel.o groupmod.o logoutd.o mkpasswd.o newusers.o useradd.o userdel.o usermod.o grpck.o pwck.o vipw.o grpconv.o grpunconv.o pwconv.o pwunconv.o
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps src/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+mostlyclean-ubinPROGRAMS:
+
+clean-ubinPROGRAMS:
+ -test -z "$(ubin_PROGRAMS)" || rm -f $(ubin_PROGRAMS)
+
+distclean-ubinPROGRAMS:
+
+maintainer-clean-ubinPROGRAMS:
+
+install-ubinPROGRAMS: $(ubin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(ubindir)
+ @list='$(ubin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(ubindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(ubindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-ubinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(ubin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(ubindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-usbinPROGRAMS:
+
+clean-usbinPROGRAMS:
+ -test -z "$(usbin_PROGRAMS)" || rm -f $(usbin_PROGRAMS)
+
+distclean-usbinPROGRAMS:
+
+maintainer-clean-usbinPROGRAMS:
+
+install-usbinPROGRAMS: $(usbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(usbindir)
+ @list='$(usbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(usbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(usbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-usbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(usbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(usbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+login: $(login_OBJECTS) $(login_DEPENDENCIES)
+ @rm -f login
+ $(LINK) $(login_LDFLAGS) $(login_OBJECTS) $(login_LDADD) $(LIBS)
+
+su: $(su_OBJECTS) $(su_DEPENDENCIES)
+ @rm -f su
+ $(LINK) $(su_LDFLAGS) $(su_OBJECTS) $(su_LDADD) $(LIBS)
+
+groups: $(groups_OBJECTS) $(groups_DEPENDENCIES)
+ @rm -f groups
+ $(LINK) $(groups_LDFLAGS) $(groups_OBJECTS) $(groups_LDADD) $(LIBS)
+
+id: $(id_OBJECTS) $(id_DEPENDENCIES)
+ @rm -f id
+ $(LINK) $(id_LDFLAGS) $(id_OBJECTS) $(id_LDADD) $(LIBS)
+
+sulogin: $(sulogin_OBJECTS) $(sulogin_DEPENDENCIES)
+ @rm -f sulogin
+ $(LINK) $(sulogin_LDFLAGS) $(sulogin_OBJECTS) $(sulogin_LDADD) $(LIBS)
+
+faillog: $(faillog_OBJECTS) $(faillog_DEPENDENCIES)
+ @rm -f faillog
+ $(LINK) $(faillog_LDFLAGS) $(faillog_OBJECTS) $(faillog_LDADD) $(LIBS)
+
+lastlog: $(lastlog_OBJECTS) $(lastlog_DEPENDENCIES)
+ @rm -f lastlog
+ $(LINK) $(lastlog_LDFLAGS) $(lastlog_OBJECTS) $(lastlog_LDADD) $(LIBS)
+
+chage: $(chage_OBJECTS) $(chage_DEPENDENCIES)
+ @rm -f chage
+ $(LINK) $(chage_LDFLAGS) $(chage_OBJECTS) $(chage_LDADD) $(LIBS)
+
+chfn: $(chfn_OBJECTS) $(chfn_DEPENDENCIES)
+ @rm -f chfn
+ $(LINK) $(chfn_LDFLAGS) $(chfn_OBJECTS) $(chfn_LDADD) $(LIBS)
+
+chsh: $(chsh_OBJECTS) $(chsh_DEPENDENCIES)
+ @rm -f chsh
+ $(LINK) $(chsh_LDFLAGS) $(chsh_OBJECTS) $(chsh_LDADD) $(LIBS)
+
+expiry: $(expiry_OBJECTS) $(expiry_DEPENDENCIES)
+ @rm -f expiry
+ $(LINK) $(expiry_LDFLAGS) $(expiry_OBJECTS) $(expiry_LDADD) $(LIBS)
+
+gpasswd: $(gpasswd_OBJECTS) $(gpasswd_DEPENDENCIES)
+ @rm -f gpasswd
+ $(LINK) $(gpasswd_LDFLAGS) $(gpasswd_OBJECTS) $(gpasswd_LDADD) $(LIBS)
+
+newgrp: $(newgrp_OBJECTS) $(newgrp_DEPENDENCIES)
+ @rm -f newgrp
+ $(LINK) $(newgrp_LDFLAGS) $(newgrp_OBJECTS) $(newgrp_LDADD) $(LIBS)
+
+passwd: $(passwd_OBJECTS) $(passwd_DEPENDENCIES)
+ @rm -f passwd
+ $(LINK) $(passwd_LDFLAGS) $(passwd_OBJECTS) $(passwd_LDADD) $(LIBS)
+
+chpasswd: $(chpasswd_OBJECTS) $(chpasswd_DEPENDENCIES)
+ @rm -f chpasswd
+ $(LINK) $(chpasswd_LDFLAGS) $(chpasswd_OBJECTS) $(chpasswd_LDADD) $(LIBS)
+
+dpasswd: $(dpasswd_OBJECTS) $(dpasswd_DEPENDENCIES)
+ @rm -f dpasswd
+ $(LINK) $(dpasswd_LDFLAGS) $(dpasswd_OBJECTS) $(dpasswd_LDADD) $(LIBS)
+
+groupadd: $(groupadd_OBJECTS) $(groupadd_DEPENDENCIES)
+ @rm -f groupadd
+ $(LINK) $(groupadd_LDFLAGS) $(groupadd_OBJECTS) $(groupadd_LDADD) $(LIBS)
+
+groupdel: $(groupdel_OBJECTS) $(groupdel_DEPENDENCIES)
+ @rm -f groupdel
+ $(LINK) $(groupdel_LDFLAGS) $(groupdel_OBJECTS) $(groupdel_LDADD) $(LIBS)
+
+groupmod: $(groupmod_OBJECTS) $(groupmod_DEPENDENCIES)
+ @rm -f groupmod
+ $(LINK) $(groupmod_LDFLAGS) $(groupmod_OBJECTS) $(groupmod_LDADD) $(LIBS)
+
+logoutd: $(logoutd_OBJECTS) $(logoutd_DEPENDENCIES)
+ @rm -f logoutd
+ $(LINK) $(logoutd_LDFLAGS) $(logoutd_OBJECTS) $(logoutd_LDADD) $(LIBS)
+
+mkpasswd: $(mkpasswd_OBJECTS) $(mkpasswd_DEPENDENCIES)
+ @rm -f mkpasswd
+ $(LINK) $(mkpasswd_LDFLAGS) $(mkpasswd_OBJECTS) $(mkpasswd_LDADD) $(LIBS)
+
+newusers: $(newusers_OBJECTS) $(newusers_DEPENDENCIES)
+ @rm -f newusers
+ $(LINK) $(newusers_LDFLAGS) $(newusers_OBJECTS) $(newusers_LDADD) $(LIBS)
+
+useradd: $(useradd_OBJECTS) $(useradd_DEPENDENCIES)
+ @rm -f useradd
+ $(LINK) $(useradd_LDFLAGS) $(useradd_OBJECTS) $(useradd_LDADD) $(LIBS)
+
+userdel: $(userdel_OBJECTS) $(userdel_DEPENDENCIES)
+ @rm -f userdel
+ $(LINK) $(userdel_LDFLAGS) $(userdel_OBJECTS) $(userdel_LDADD) $(LIBS)
+
+usermod: $(usermod_OBJECTS) $(usermod_DEPENDENCIES)
+ @rm -f usermod
+ $(LINK) $(usermod_LDFLAGS) $(usermod_OBJECTS) $(usermod_LDADD) $(LIBS)
+
+grpck: $(grpck_OBJECTS) $(grpck_DEPENDENCIES)
+ @rm -f grpck
+ $(LINK) $(grpck_LDFLAGS) $(grpck_OBJECTS) $(grpck_LDADD) $(LIBS)
+
+pwck: $(pwck_OBJECTS) $(pwck_DEPENDENCIES)
+ @rm -f pwck
+ $(LINK) $(pwck_LDFLAGS) $(pwck_OBJECTS) $(pwck_LDADD) $(LIBS)
+
+vipw: $(vipw_OBJECTS) $(vipw_DEPENDENCIES)
+ @rm -f vipw
+ $(LINK) $(vipw_LDFLAGS) $(vipw_OBJECTS) $(vipw_LDADD) $(LIBS)
+
+grpconv: $(grpconv_OBJECTS) $(grpconv_DEPENDENCIES)
+ @rm -f grpconv
+ $(LINK) $(grpconv_LDFLAGS) $(grpconv_OBJECTS) $(grpconv_LDADD) $(LIBS)
+
+grpunconv: $(grpunconv_OBJECTS) $(grpunconv_DEPENDENCIES)
+ @rm -f grpunconv
+ $(LINK) $(grpunconv_LDFLAGS) $(grpunconv_OBJECTS) $(grpunconv_LDADD) $(LIBS)
+
+pwconv: $(pwconv_OBJECTS) $(pwconv_DEPENDENCIES)
+ @rm -f pwconv
+ $(LINK) $(pwconv_LDFLAGS) $(pwconv_OBJECTS) $(pwconv_LDADD) $(LIBS)
+
+pwunconv: $(pwunconv_OBJECTS) $(pwunconv_DEPENDENCIES)
+ @rm -f pwunconv
+ $(LINK) $(pwunconv_LDFLAGS) $(pwunconv_OBJECTS) $(pwunconv_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = src
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+chage.o: chage.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \
+ ../lib/shadowio.h
+chfn.o: chfn.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \
+ ../lib/getdef.h ../lib/pwauth.h
+chpasswd.o: chpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \
+ ../lib/shadowio.h
+chsh.o: chsh.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \
+ ../lib/getdef.h ../lib/pwauth.h
+dpasswd.o: dpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/dialup.h
+expiry.o: expiry.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+faillog.o: faillog.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/faillog.h
+gpasswd.o: gpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/groupio.h \
+ ../lib/sgroupio.h
+groupadd.o: groupadd.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/prototypes.h ../libmisc/chkname.h \
+ ../lib/getdef.h ../lib/groupio.h ../lib/sgroupio.h
+groupdel.o: groupdel.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/groupio.h \
+ ../lib/sgroupio.h
+groupmod.o: groupmod.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \
+ ../lib/groupio.h ../lib/sgroupio.h
+groups.o: groups.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+grpck.o: grpck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \
+ ../lib/commonio.h ../lib/groupio.h ../lib/sgroupio.h
+grpconv.o: grpconv.c ../config.h ../lib/prototypes.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/groupio.h ../lib/sgroupio.h \
+ ../lib/rcsid.h
+grpunconv.o: grpunconv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/groupio.h \
+ ../lib/sgroupio.h
+id.o: id.c ../config.h ../lib/rcsid.h ../lib/defines.h ../lib/gshadow_.h
+lastlog.o: lastlog.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+login.o: login.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/faillog.h \
+ ../libmisc/failure.h ../lib/pwauth.h ../lib/getdef.h \
+ ../lib/dialchk.h
+logoutd.o: logoutd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+mkpasswd.o: mkpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h
+newgrp.o: newgrp.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
+newusers.o: newusers.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h \
+ ../lib/pwio.h ../lib/groupio.h ../lib/shadowio.h
+passwd.o: passwd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h \
+ ../lib/shadowio.h ../lib/pwio.h ../lib/getdef.h
+pwck.o: pwck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \
+ ../lib/commonio.h ../lib/pwio.h ../lib/shadowio.h
+pwconv.o: pwconv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \
+ ../lib/shadowio.h ../lib/getdef.h
+pwunconv.o: pwunconv.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/prototypes.h ../lib/pwio.h \
+ ../lib/shadowio.h
+sulogin.o: sulogin.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h \
+ ../lib/pwauth.h
+su.o: su.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h \
+ ../lib/getdef.h
+useradd.o: useradd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \
+ ../lib/pwauth.h ../lib/faillog.h ../lib/groupio.h \
+ ../lib/sgroupio.h ../lib/pwio.h ../lib/shadowio.h \
+ ../lib/getdef.h
+userdel.o: userdel.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h \
+ ../lib/pwauth.h ../lib/groupio.h ../lib/pwio.h \
+ ../lib/shadowio.h ../lib/sgroupio.h
+usermod.o: usermod.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
+ ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \
+ ../lib/faillog.h ../lib/pwauth.h ../lib/getdef.h \
+ ../lib/groupio.h ../lib/sgroupio.h ../lib/pwio.h \
+ ../lib/shadowio.h
+vipw.o: vipw.c ../config.h ../lib/rcsid.h ../lib/defines.h \
+ ../lib/gshadow_.h ../lib/prototypes.h ../lib/pwio.h \
+ ../lib/shadowio.h ../lib/groupio.h ../lib/sgroupio.h
+
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-ubinPROGRAMS install-usbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-ubinPROGRAMS \
+ uninstall-usbinPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(ubindir) \
+ $(DESTDIR)$(usbindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \
+ mostlyclean-ubinPROGRAMS mostlyclean-usbinPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-ubinPROGRAMS \
+ clean-usbinPROGRAMS clean-compile clean-libtool \
+ clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \
+ distclean-ubinPROGRAMS distclean-usbinPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-ubinPROGRAMS \
+ maintainer-clean-usbinPROGRAMS maintainer-clean-compile \
+ maintainer-clean-libtool maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-ubinPROGRAMS distclean-ubinPROGRAMS clean-ubinPROGRAMS \
+maintainer-clean-ubinPROGRAMS uninstall-ubinPROGRAMS \
+install-ubinPROGRAMS mostlyclean-usbinPROGRAMS distclean-usbinPROGRAMS \
+clean-usbinPROGRAMS maintainer-clean-usbinPROGRAMS \
+uninstall-usbinPROGRAMS install-usbinPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-exec-hook:
+ for i in $(suidbins); do \
+ chmod 4755 $(DESTDIR)$(bindir)/$$i; \
+ done
+
+install-data-hook:
+ for i in $(suidubins); do \
+ chmod 4755 $(DESTDIR)$(ubindir)/$$i; \
+ done
+ rm -f $(DESTDIR)$(ubindir)/sg
+ ln -s newgrp $(DESTDIR)$(ubindir)/sg
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/current/src/chage.c b/current/src/chage.c
new file mode 100644
index 00000000..fd1e5d64
--- /dev/null
+++ b/current/src/chage.c
@@ -0,0 +1,841 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: chage.c,v 1.18 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <ctype.h>
+#include <time.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <pwd.h>
+
+/*
+ * chage depends on some form of aging being present. It makes no sense
+ * to have a program that has no input.
+ */
+
+#ifdef SHADOWPWD
+#ifndef AGING
+#define AGING
+#endif /* AGING */
+#else /* !SHADOWPWD */
+#if !defined(ATT_AGE) && defined(AGING)
+#undef AGING
+#endif /* !ATT_AGE && AGING */
+#endif /* SHADOWPWD */
+
+static char *Prog;
+static int amroot;
+
+#ifdef AGING /*{*/
+
+/*
+ * Global variables
+ */
+
+static long mindays;
+static long maxdays;
+static long lastday;
+#ifdef SHADOWPWD
+static long warndays;
+static long inactdays;
+static long expdays;
+#endif
+
+/*
+ * External identifiers
+ */
+
+extern long a64l();
+extern char *l64a();
+
+#include "pwio.h"
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+
+extern int optind;
+extern char *optarg;
+#ifdef NDBM
+extern int pw_dbm_mode;
+#ifdef SHADOWPWD
+extern int sp_dbm_mode;
+#endif
+#endif
+
+/*
+ * #defines for messages. This facilitates foreign language conversion
+ * since all messages are defined right here.
+ */
+
+/*
+ * xgettext doesn't like #defines, so now we only leave untranslated
+ * messages here. -MM
+ */
+
+#define AGE_CHANGED "changed password expiry for %s\n"
+#define LOCK_FAIL "failed locking %s\n"
+#define OPEN_FAIL "failed opening %s\n"
+#define WRITE_FAIL "failed updating %s\n"
+#define CLOSE_FAIL "failed rewriting %s\n"
+
+#define EPOCH "1969-12-31"
+
+#ifdef SHADOWPWD
+#define DBMERROR2 "error updating DBM shadow entry.\n"
+#else
+#define DBMERROR2 "error updating DBM passwd entry.\n"
+#endif
+
+/* local function prototypes */
+static void usage(void);
+static void date_to_str(char *, size_t, time_t);
+static int new_fields(void);
+static void print_date(time_t);
+static void list_fields(void);
+static void cleanup(int);
+
+
+/*
+ * isnum - determine whether or not a string is a number
+ */
+int
+isnum(const char *s)
+{
+ while (*s) {
+ if (!isdigit(*s))
+ return 0;
+ s++;
+ }
+ return 1;
+}
+
+/*
+ * usage - print command line syntax and exit
+ */
+
+static void
+usage(void)
+{
+#ifdef SHADOWPWD
+ fprintf(stderr, _("Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"), Prog);
+#else
+ fprintf(stderr, _("Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"), Prog);
+#endif
+ exit(1);
+}
+
+static void
+date_to_str(char *buf, size_t maxsize, time_t date)
+{
+ struct tm *tp;
+
+ tp = gmtime(&date);
+#ifdef HAVE_STRFTIME
+ strftime(buf, maxsize, "%Y-%m-%d", tp);
+#else
+ snprintf(buf, maxsize, "%04d-%02d-%02d",
+ tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday);
+#endif /* HAVE_STRFTIME */
+}
+
+/*
+ * new_fields - change the user's password aging information interactively.
+ *
+ * prompt the user for all of the password age values. set the fields
+ * from the user's response, or leave alone if nothing was entered. the
+ * value (-1) is used to indicate the field should be removed if possible.
+ * any other negative value is an error. very large positive values will
+ * be handled elsewhere.
+ */
+
+static int
+new_fields(void)
+{
+ char buf[200];
+ char *cp;
+
+ printf(_("Enter the new value, or press return for the default\n\n"));
+
+ snprintf(buf, sizeof buf, "%ld", mindays);
+ change_field(buf, sizeof buf, _("Minimum Password Age"));
+ if (((mindays = strtol (buf, &cp, 10)) == 0 && *cp) || mindays < -1)
+ return 0;
+
+ snprintf(buf, sizeof buf, "%ld", maxdays);
+ change_field(buf, sizeof buf, _("Maximum Password Age"));
+ if (((maxdays = strtol (buf, &cp, 10)) == 0 && *cp) || maxdays < -1)
+ return 0;
+
+ date_to_str(buf, sizeof buf, lastday * SCALE);
+
+ change_field(buf, sizeof buf, _("Last Password Change (YYYY-MM-DD)"));
+
+ if (strcmp (buf, EPOCH) == 0)
+ lastday = -1;
+ else if ((lastday = strtoday (buf)) == -1)
+ return 0;
+
+#ifdef SHADOWPWD
+ snprintf(buf, sizeof buf, "%ld", warndays);
+ change_field (buf, sizeof buf, _("Password Expiration Warning"));
+ if (((warndays = strtol (buf, &cp, 10)) == 0 && *cp) || warndays < -1)
+ return 0;
+
+ snprintf(buf, sizeof buf, "%ld", inactdays);
+ change_field(buf, sizeof buf, _("Password Inactive"));
+ if (((inactdays = strtol (buf, &cp, 10)) == 0 && *cp) || inactdays < -1)
+ return 0;
+
+ date_to_str(buf, sizeof buf, expdays * SCALE);
+
+ change_field(buf, sizeof buf, _("Account Expiration Date (YYYY-MM-DD)"));
+
+ if (strcmp (buf, EPOCH) == 0)
+ expdays = -1;
+ else if ((expdays = strtoday (buf)) == -1)
+ return 0;
+#endif /* SHADOWPWD */
+
+ return 1;
+}
+
+static void
+print_date(time_t date)
+{
+#ifdef HAVE_STRFTIME
+ struct tm *tp;
+ char buf[80];
+
+ tp = gmtime(&date);
+ strftime(buf, sizeof buf, "%b %d, %Y", tp);
+ puts(buf);
+#else
+ struct tm *tp;
+ char *cp;
+
+ tp = gmtime(&date);
+ cp = asctime(tp);
+ printf("%6.6s, %4.4s\n", cp + 4, cp + 20);
+#endif
+}
+
+/*
+ * list_fields - display the current values of the expiration fields
+ *
+ * display the password age information from the password fields. date
+ * values will be displayed as a calendar date, or the word "Never" if
+ * the date is 1/1/70, which is day number 0.
+ */
+
+static void
+list_fields(void)
+{
+ long changed = 0;
+ long expires;
+
+ /*
+ * Start with the easy numbers - the number of days before the
+ * password can be changed, the number of days after which the
+ * password must be chaged, the number of days before the
+ * password expires that the user is told, and the number of
+ * days after the password expires that the account becomes
+ * unusable.
+ */
+
+ printf(_("Minimum:\t%ld\n"), mindays);
+ printf(_("Maximum:\t%ld\n"), maxdays);
+#ifdef SHADOWPWD
+ printf(_("Warning:\t%ld\n"), warndays);
+ printf(_("Inactive:\t%ld\n"), inactdays);
+#endif
+
+ /*
+ * The "last change" date is either "Never" or the date the
+ * password was last modified. The date is the number of
+ * days since 1/1/1970.
+ */
+
+ printf(_("Last Change:\t\t"));
+ if (lastday <= 0) {
+ printf(_("Never\n"));
+ } else {
+ changed = lastday * SCALE;
+ print_date(changed);
+ }
+
+ /*
+ * The password expiration date is determined from the last
+ * change date plus the number of days the password is valid
+ * for.
+ */
+
+ printf(_("Password Expires:\t"));
+ if (lastday <= 0 || maxdays >= 10000*(DAY/SCALE) || maxdays <= 0) {
+ printf (_("Never\n"));
+ } else {
+ expires = changed + maxdays * SCALE;
+ print_date(expires);
+ }
+
+#ifdef SHADOWPWD
+ /*
+ * The account becomes inactive if the password is expired
+ * for more than "inactdays". The expiration date is calculated
+ * and the number of inactive days is added. The resulting date
+ * is when the active will be disabled.
+ */
+
+ printf(_("Password Inactive:\t"));
+ if (lastday <= 0 || inactdays <= 0 ||
+ maxdays >= 10000*(DAY/SCALE) || maxdays <= 0) {
+ printf (_("Never\n"));
+ } else {
+ expires = changed + (maxdays + inactdays) * SCALE;
+ print_date(expires);
+ }
+
+ /*
+ * The account will expire on the given date regardless of the
+ * password expiring or not.
+ */
+
+ printf(_("Account Expires:\t"));
+ if (expdays <= 0) {
+ printf (_("Never\n"));
+ } else {
+ expires = expdays * SCALE;
+ print_date(expires);
+ }
+#endif
+}
+
+/*
+ * chage - change a user's password aging information
+ *
+ * This command controls the password aging information.
+ *
+ * The valid options are
+ *
+ * -m minimum number of days before password change (*)
+ * -M maximim number of days before password change (*)
+ * -d last password change date (*)
+ * -l password aging information
+ * -W expiration warning days (*)
+ * -I password inactive after expiration (*)
+ * -E account expiration date (*)
+ *
+ * (*) requires root permission to execute.
+ *
+ * All of the time fields are entered in the internal format
+ * which is either seconds or days.
+ *
+ * The options -W, -I and -E all depend on the SHADOWPWD
+ * macro being defined.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int flag;
+ int lflg = 0;
+ int mflg = 0;
+ int Mflg = 0;
+ int dflg = 0;
+#ifdef SHADOWPWD
+ int Wflg = 0;
+ int Iflg = 0;
+ int Eflg = 0;
+ const struct spwd *sp;
+ struct spwd spwd;
+#else
+ char new_age[5];
+#endif
+ uid_t ruid;
+ const struct passwd *pw;
+ struct passwd pwent;
+ char name[BUFSIZ];
+
+ sanitize_env();
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ ruid = getuid();
+ amroot = (ruid == 0);
+
+ /*
+ * Get the program name so that error messages can use it.
+ */
+
+ Prog = Basename(argv[0]);
+
+ OPENLOG("chage");
+#ifdef NDBM
+#ifdef SHADOWPWD
+ sp_dbm_mode = O_RDWR;
+#endif
+ pw_dbm_mode = O_RDWR;
+#endif
+
+ /*
+ * Parse the flags. The difference between password file
+ * formats includes the number of fields, and whether the
+ * dates are entered as days or weeks. Shadow password
+ * file info =must= be entered in days, while regular
+ * password file info =must= be entered in weeks.
+ */
+
+#ifdef SHADOWPWD
+#define FLAGS "lm:M:W:I:E:d:"
+#else
+#define FLAGS "lm:M:d:"
+#endif
+ while ((flag = getopt(argc, argv, FLAGS)) != EOF) {
+#undef FLAGS
+ switch (flag) {
+ case 'l':
+ lflg++;
+ break;
+ case 'm':
+ mflg++;
+ mindays = strtol (optarg, 0, 10);
+ break;
+ case 'M':
+ Mflg++;
+ maxdays = strtol (optarg, 0, 10);
+ break;
+ case 'd':
+ dflg++;
+ if (!isnum(optarg))
+ lastday = strtoday (optarg);
+ else
+ lastday = strtol (optarg, 0, 10);
+ break;
+#ifdef SHADOWPWD
+ case 'W':
+ Wflg++;
+ warndays = strtol (optarg, 0, 10);
+ break;
+ case 'I':
+ Iflg++;
+ inactdays = strtol (optarg, 0, 10);
+ break;
+ case 'E':
+ Eflg++;
+ if (!isnum(optarg))
+ expdays = strtoday (optarg);
+ else
+ expdays = strtol (optarg, 0, 10);
+ break;
+#endif
+ default:
+ usage ();
+ }
+ }
+
+ /*
+ * Make certain the flags do not conflict and that there is
+ * a user name on the command line.
+ */
+
+ if (argc != optind + 1)
+ usage ();
+
+#ifdef SHADOWPWD
+ if (lflg && (mflg || Mflg || dflg || Wflg || Iflg || Eflg))
+#else
+ if (lflg && (mflg || Mflg || dflg))
+#endif
+ {
+ fprintf (stderr, _("%s: do not include \"l\" with other flags\n"), Prog);
+ closelog();
+ usage ();
+ }
+
+ /*
+ * An unprivileged user can ask for their own aging information,
+ * but only root can change it, or list another user's aging
+ * information.
+ */
+
+ if (!amroot && !lflg) {
+ fprintf (stderr, _("%s: permission denied\n"), Prog);
+ closelog();
+ exit (1);
+ }
+
+ /*
+ * Lock and open the password file. This loads all of the
+ * password file entries into memory. Then we get a pointer
+ * to the password file entry for the requested user.
+ */
+ /* We don't lock the password file if we are not root */
+ if (amroot && !pw_lock()) {
+ fprintf(stderr, _("%s: can't lock password file\n"), Prog);
+ SYSLOG((LOG_ERR, LOCK_FAIL, PASSWD_FILE));
+ closelog();
+ exit(1);
+ }
+ if (!pw_open((!amroot || lflg) ? O_RDONLY:O_RDWR)) {
+ fprintf(stderr, _("%s: can't open password file\n"), Prog);
+ cleanup(1);
+ SYSLOG((LOG_ERR, OPEN_FAIL, PASSWD_FILE));
+ closelog();
+ exit(1);
+ }
+ if (!(pw = pw_locate(argv[optind]))) {
+ fprintf(stderr, _("%s: unknown user: %s\n"), Prog, argv[optind]);
+ cleanup(1);
+ closelog();
+ exit(1);
+ }
+
+ pwent = *pw;
+ STRFCPY(name, pwent.pw_name);
+
+#ifdef SHADOWPWD
+ /*
+ * For shadow password files we have to lock the file and
+ * read in the entries as was done for the password file.
+ * The user entries does not have to exist in this case;
+ * a new entry will be created for this user if one does
+ * not exist already.
+ */
+ /* We don't lock the shadow file if we are not root */
+ if (amroot && !spw_lock()) {
+ fprintf(stderr, _("%s: can't lock shadow password file\n"), Prog);
+ cleanup(1);
+ SYSLOG((LOG_ERR, LOCK_FAIL, SHADOW_FILE));
+ closelog();
+ exit(1);
+ }
+ if (!spw_open((!amroot || lflg) ? O_RDONLY : O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow password file\n"), Prog);
+ cleanup(2);
+ SYSLOG((LOG_ERR, OPEN_FAIL, SHADOW_FILE));
+ closelog();
+ exit(1);
+ }
+
+ sp = spw_locate(argv[optind]);
+
+ /*
+ * Set the fields that aren't being set from the command line
+ * from the password file.
+ */
+
+ if (sp) {
+ spwd = *sp;
+
+ if (! Mflg)
+ maxdays = spwd.sp_max;
+ if (! mflg)
+ mindays = spwd.sp_min;
+ if (! dflg)
+ lastday = spwd.sp_lstchg;
+ if (! Wflg)
+ warndays = spwd.sp_warn;
+ if (! Iflg)
+ inactdays = spwd.sp_inact;
+ if (! Eflg)
+ expdays = spwd.sp_expire;
+ }
+#ifdef ATT_AGE
+ else
+#endif /* ATT_AGE */
+#endif /* SHADOWPWD */
+#ifdef ATT_AGE
+ {
+ if (pwent.pw_age && strlen (pwent.pw_age) >= 2) {
+ if (! Mflg)
+ maxdays = c64i (pwent.pw_age[0]) * (WEEK/SCALE);
+ if (! mflg)
+ mindays = c64i (pwent.pw_age[1]) * (WEEK/SCALE);
+ if (! dflg && strlen (pwent.pw_age) == 4)
+ lastday = a64l (pwent.pw_age+2) * (WEEK/SCALE);
+ } else {
+ mindays = 0;
+ maxdays = 10000L * (DAY/SCALE);
+ lastday = -1;
+ }
+#ifdef SHADOWPWD
+ warndays = inactdays = expdays = -1;
+#endif /* SHADOWPWD */
+ }
+#endif /* ATT_AGE */
+
+ /*
+ * Print out the expiration fields if the user has
+ * requested the list option.
+ */
+
+ if (lflg) {
+ if (!amroot && (ruid != pwent.pw_uid)) {
+ fprintf(stderr, _("%s: permission denied\n"), Prog);
+ closelog();
+ exit(1);
+ }
+ list_fields();
+ cleanup(2);
+ closelog();
+ exit(0);
+ }
+
+ /*
+ * If none of the fields were changed from the command line,
+ * let the user interactively change them.
+ */
+
+#ifdef SHADOWPWD
+ if (! mflg && ! Mflg && ! dflg && ! Wflg && ! Iflg && ! Eflg)
+#else
+ if (! mflg && ! Mflg && ! dflg)
+#endif
+ {
+ printf(_("Changing the aging information for %s\n"), name);
+ if (!new_fields()) {
+ fprintf(stderr, _("%s: error changing fields\n"), Prog);
+ cleanup(2);
+ closelog();
+ exit(1);
+ }
+ }
+
+#ifdef SHADOWPWD
+ /*
+ * There was no shadow entry. The new entry will have the
+ * encrypted password transferred from the normal password
+ * file along with the aging information.
+ */
+
+ if (sp == 0) {
+ sp = &spwd;
+ memzero(&spwd, sizeof spwd);
+
+ spwd.sp_namp = xstrdup (pwent.pw_name);
+ spwd.sp_pwdp = xstrdup (pwent.pw_passwd);
+ spwd.sp_flag = -1;
+
+ pwent.pw_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
+#ifdef ATT_AGE
+ pwent.pw_age = "";
+#endif
+ if (!pw_update(&pwent)) {
+ fprintf(stderr, _("%s: can't update password file\n"), Prog);
+ cleanup(2);
+ SYSLOG((LOG_ERR, WRITE_FAIL, PASSWD_FILE));
+ closelog();
+ exit(1);
+ }
+#ifdef NDBM
+ (void) pw_dbm_update (&pwent);
+ endpwent ();
+#endif
+ }
+#endif /* SHADOWPWD */
+
+#ifdef SHADOWPWD
+
+ /*
+ * Copy the fields back to the shadow file entry and
+ * write the modified entry back to the shadow file.
+ * Closing the shadow and password files will commit
+ * any changes that have been made.
+ */
+
+ spwd.sp_max = maxdays;
+ spwd.sp_min = mindays;
+ spwd.sp_lstchg = lastday;
+ spwd.sp_warn = warndays;
+ spwd.sp_inact = inactdays;
+ spwd.sp_expire = expdays;
+
+ if (!spw_update(&spwd)) {
+ fprintf(stderr, _("%s: can't update shadow password file\n"), Prog);
+ cleanup(2);
+ SYSLOG((LOG_ERR, WRITE_FAIL, SHADOW_FILE));
+ closelog();
+ exit(1);
+ }
+#else /* !SHADOWPWD */
+
+ /*
+ * fill in the new_age string with the new values
+ */
+
+ if (maxdays > (63 * 7) && mindays == 0) {
+ new_age[0] = '\0';
+ } else {
+ if (maxdays > (63 * 7))
+ maxdays = 63 * 7;
+
+ if (mindays > (63 * 7))
+ mindays = 63 * 7;
+
+ new_age[0] = i64c (maxdays / 7);
+ new_age[1] = i64c ((mindays + 6) / 7);
+
+ if (lastday == 0)
+ new_age[2] = '\0';
+ else
+ strcpy (new_age + 2, l64a (lastday / 7));
+
+ }
+ pwent.pw_age = new_age;
+
+ if (!pw_update(&pwent)) {
+ fprintf(stderr, _("%s: can't update password file\n"), Prog);
+ cleanup(2);
+ SYSLOG((LOG_ERR, WRITE_FAIL, PASSWD_FILE));
+ closelog();
+ exit(1);
+ }
+#endif /* SHADOWPWD */
+
+#ifdef NDBM
+#ifdef SHADOWPWD
+
+ /*
+ * See if the shadow DBM file exists and try to update it.
+ */
+
+ if (sp_dbm_present() && !sp_dbm_update(&spwd)) {
+ fprintf(stderr, _("Error updating the DBM password entry.\n"));
+ cleanup(2);
+ SYSLOG((LOG_ERR, DBMERROR2));
+ closelog();
+ exit(1);
+ }
+ endspent();
+
+#else /* !SHADOWPWD */
+
+ /*
+ * See if the password DBM file exists and try to update it.
+ */
+
+ if (pw_dbm_present() && !pw_dbm_update(&pwent)) {
+ fprintf(stderr, _("Error updating the DBM password entry.\n"));
+ cleanup(2);
+ SYSLOG((LOG_ERR, DBMERROR2));
+ closelog();
+ exit(1);
+ }
+ endpwent ();
+#endif /* SHADOWPWD */
+#endif /* NDBM */
+
+#ifdef SHADOWPWD
+ /*
+ * Now close the shadow password file, which will cause all
+ * of the entries to be re-written.
+ */
+
+ if (!spw_close()) {
+ fprintf(stderr, _("%s: can't rewrite shadow password file\n"), Prog);
+ cleanup(2);
+ SYSLOG((LOG_ERR, CLOSE_FAIL, SHADOW_FILE));
+ closelog();
+ exit(1);
+ }
+#endif /* SHADOWPWD */
+
+ /*
+ * Close the password file. If any entries were modified, the
+ * file will be re-written.
+ */
+
+ if (!pw_close()) {
+ fprintf(stderr, _("%s: can't rewrite password file\n"), Prog);
+ cleanup(2);
+ SYSLOG((LOG_ERR, CLOSE_FAIL, PASSWD_FILE));
+ closelog();
+ exit(1);
+ }
+ cleanup(2);
+ SYSLOG((LOG_INFO, AGE_CHANGED, name));
+ closelog();
+ exit(0);
+ /*NOTREACHED*/
+}
+
+/*
+ * cleanup - unlock any locked password files
+ */
+
+static void
+cleanup(int state)
+{
+ switch (state) {
+ case 2:
+#ifdef SHADOWPWD
+ if (amroot)
+ spw_unlock();
+#endif
+ case 1:
+ if (amroot)
+ pw_unlock();
+ case 0:
+ break;
+ }
+}
+
+#else /*} !AGING {*/
+
+/*
+ * chage - but there is no age info!
+ */
+
+int
+main(int argc, char **argv)
+{
+ char *Prog;
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ fprintf (stderr, _("%s: no aging information present\n"), Prog);
+ exit(1);
+}
+
+#endif /*} AGING */
+
diff --git a/current/src/chfn.c b/current/src/chfn.c
new file mode 100644
index 00000000..413ff33f
--- /dev/null
+++ b/current/src/chfn.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: chfn.c,v 1.17 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <pwd.h>
+#include "pwio.h"
+#include "getdef.h"
+#include "pwauth.h"
+
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+#ifdef USE_PAM
+#include "pam_defs.h"
+#endif
+
+/*
+ * Global variables.
+ */
+
+static char *Prog;
+static char fullnm[BUFSIZ];
+static char roomno[BUFSIZ];
+static char workph[BUFSIZ];
+static char homeph[BUFSIZ];
+static char slop[BUFSIZ];
+static int amroot;
+
+/*
+ * External identifiers
+ */
+
+extern int optind;
+extern char *optarg;
+#ifdef NDBM
+extern int pw_dbm_mode;
+#endif
+
+/*
+ * #defines for messages. This facilitates foreign language conversion
+ * since all messages are defined right here.
+ */
+
+#define WRONGPWD2 "incorrect password for `%s'"
+#define PWDBUSY2 "can't lock /etc/passwd\n"
+#define OPNERROR2 "can't open /etc/passwd\n"
+#define UPDERROR2 "error updating passwd entry\n"
+#define DBMERROR2 "error updating DBM passwd entry.\n"
+#define NOTROOT2 "can't setuid(0).\n"
+#define CLSERROR2 "can't rewrite /etc/passwd.\n"
+#define UNLKERROR2 "can't unlock /etc/passwd.\n"
+#define CHGGECOS "changed user `%s' information.\n"
+
+/* local function prototypes */
+static void usage(void);
+static int may_change_field(int);
+static void new_fields(void);
+static char *copy_field(char *, char *, char *);
+
+/*
+ * usage - print command line syntax and exit
+ */
+
+static void
+usage(void)
+{
+ if (amroot)
+ fprintf(stderr,
+ _("Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n\t[ -h home_ph ] [ -o other ] [ user ]\n"),
+ Prog);
+ else
+ fprintf(stderr,
+ _("Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"),
+ Prog);
+ exit(1);
+}
+
+
+static int
+may_change_field(int field)
+{
+ const char *cp;
+
+ /*
+ * CHFN_RESTRICT can now specify exactly which fields may be
+ * changed by regular users, by using any combination of the
+ * following letters:
+ * f - full name
+ * r - room number
+ * w - work phone
+ * h - home phone
+ *
+ * This makes it possible to disallow changing the room number
+ * information, for example - this feature was suggested by
+ * Maciej 'Tycoon' Majchrowski.
+ *
+ * For backward compatibility, "yes" is equivalent to "rwh",
+ * "no" is equivalent to "frwh". Only root can change anything
+ * if the string is empty or not defined at all.
+ */
+ if (amroot)
+ return 1;
+ cp = getdef_str("CHFN_RESTRICT");
+ if (!cp)
+ cp = "";
+ else if (strcmp(cp, "yes") == 0)
+ cp = "rwh";
+ else if (strcmp(cp, "no") == 0)
+ cp = "frwh";
+ if (strchr(cp, field))
+ return 1;
+ return 0;
+}
+
+/*
+ * new_fields - change the user's GECOS information interactively
+ *
+ * prompt the user for each of the four fields and fill in the fields
+ * from the user's response, or leave alone if nothing was entered.
+ */
+
+static void
+new_fields(void)
+{
+ printf(_("Enter the new value, or press return for the default\n"));
+
+ if (may_change_field('f'))
+ change_field(fullnm, sizeof fullnm, _("Full Name"));
+ else
+ printf(_("\tFull Name: %s\n"), fullnm);
+
+ if (may_change_field('r'))
+ change_field(roomno, sizeof roomno, _("Room Number"));
+ else
+ printf(_("\tRoom Number: %s\n"), roomno);
+
+ if (may_change_field('w'))
+ change_field(workph, sizeof workph, _("Work Phone"));
+ else
+ printf(_("\tWork Phone: %s\n"), workph);
+
+ if (may_change_field('h'))
+ change_field(homeph, sizeof homeph, _("Home Phone"));
+ else
+ printf(_("\tHome Phone: %s\n"), homeph);
+
+ if (amroot)
+ change_field(slop, sizeof slop, _("Other"));
+}
+
+/*
+ * copy_field - get the next field from the gecos field
+ *
+ * copy_field copies the next field from the gecos field, returning a
+ * pointer to the field which follows, or NULL if there are no more
+ * fields.
+ *
+ * in - the current GECOS field
+ * out - where to copy the field to
+ * extra - fields with '=' get copied here
+ */
+
+static char *
+copy_field(char *in, char *out, char *extra)
+{
+ char *cp = NULL;
+
+ while (in) {
+ if ((cp = strchr (in, ',')))
+ *cp++ = '\0';
+
+ if (! strchr (in, '='))
+ break;
+
+ if (extra) {
+ if (extra[0])
+ strcat (extra, ",");
+
+ strcat (extra, in);
+ }
+ in = cp;
+ }
+ if (in && out)
+ strcpy (out, in);
+
+ return cp;
+}
+
+
+/*
+ * chfn - change a user's password file information
+ *
+ * This command controls the GECOS field information in the
+ * password file entry.
+ *
+ * The valid options are
+ *
+ * -f full name
+ * -r room number
+ * -w work phone number
+ * -h home phone number
+ * -o other information (*)
+ *
+ * (*) requires root permission to execute.
+ */
+
+int
+main(int argc, char **argv)
+{
+ char *cp; /* temporary character pointer */
+ const struct passwd *pw; /* password file entry */
+ struct passwd pwent; /* modified password file entry */
+ char old_gecos[BUFSIZ]; /* buffer for old GECOS fields */
+ char new_gecos[BUFSIZ]; /* buffer for new GECOS fields */
+ int flag; /* flag currently being processed */
+ int fflg = 0; /* -f - set full name */
+ int rflg = 0; /* -r - set room number */
+ int wflg = 0; /* -w - set work phone number */
+ int hflg = 0; /* -h - set home phone number */
+ int oflg = 0; /* -o - set other information */
+ char *user;
+
+ sanitize_env();
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /*
+ * This command behaves different for root and non-root
+ * users.
+ */
+
+ amroot = (getuid () == 0);
+#ifdef NDBM
+ pw_dbm_mode = O_RDWR;
+#endif
+
+ /*
+ * Get the program name. The program name is used as a
+ * prefix to most error messages.
+ */
+
+ Prog = Basename(argv[0]);
+
+ OPENLOG("chfn");
+
+ /*
+ * The remaining arguments will be processed one by one and
+ * executed by this command. The name is the last argument
+ * if it does not begin with a "-", otherwise the name is
+ * determined from the environment and must agree with the
+ * real UID. Also, the UID will be checked for any commands
+ * which are restricted to root only.
+ */
+
+ while ((flag = getopt (argc, argv, "f:r:w:h:o:")) != EOF) {
+ switch (flag) {
+ case 'f':
+ if (!may_change_field('f')) {
+ fprintf(stderr, _("%s: Permission denied.\n"), Prog);
+ exit(1);
+ }
+ fflg++;
+ STRFCPY(fullnm, optarg);
+ break;
+ case 'r':
+ if (!may_change_field('r')) {
+ fprintf(stderr, _("%s: Permission denied.\n"), Prog);
+ exit(1);
+ }
+ rflg++;
+ STRFCPY(roomno, optarg);
+ break;
+ case 'w':
+ if (!may_change_field('w')) {
+ fprintf(stderr, _("%s: Permission denied.\n"), Prog);
+ exit(1);
+ }
+ wflg++;
+ STRFCPY(workph, optarg);
+ break;
+ case 'h':
+ if (!may_change_field('h')) {
+ fprintf(stderr, _("%s: Permission denied.\n"), Prog);
+ exit(1);
+ }
+ hflg++;
+ STRFCPY(homeph, optarg);
+ break;
+ case 'o':
+ if (!amroot) {
+ fprintf(stderr, _("%s: Permission denied.\n"), Prog);
+ exit(1);
+ }
+ oflg++;
+ STRFCPY(slop, optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ /*
+ * Get the name of the user to check. It is either
+ * the command line name, or the name getlogin()
+ * returns.
+ */
+
+ if (optind < argc) {
+ user = argv[optind];
+ pw = getpwnam(user);
+ if (!pw) {
+ fprintf(stderr, _("%s: Unknown user %s\n"), Prog, user);
+ exit(1);
+ }
+ } else {
+ pw = get_my_pwent();
+ if (!pw) {
+ fprintf(stderr, _("%s: Cannot determine your user name.\n"), Prog);
+ exit(1);
+ }
+ user = xstrdup(pw->pw_name);
+ }
+
+#ifdef USE_NIS
+ /*
+ * Now we make sure this is a LOCAL password entry for
+ * this user ...
+ */
+
+ if (__ispwNIS ()) {
+ char *nis_domain;
+ char *nis_master;
+
+ fprintf (stderr, _("%s: cannot change user `%s' on NIS client.\n"), Prog, user);
+
+ if (! yp_get_default_domain (&nis_domain) &&
+ ! yp_master (nis_domain, "passwd.byname",
+ &nis_master)) {
+ fprintf (stderr, _("%s: `%s' is the NIS master for this client.\n"), Prog, nis_master);
+ }
+ exit (1);
+ }
+#endif
+
+ /*
+ * Non-privileged users are only allowed to change the
+ * gecos field if the UID of the user matches the current
+ * real UID.
+ */
+
+ if (!amroot && pw->pw_uid != getuid()) {
+ fprintf (stderr, _("%s: Permission denied.\n"), Prog);
+ closelog();
+ exit(1);
+ }
+
+ /*
+ * Non-privileged users are optionally authenticated
+ * (must enter the password of the user whose information
+ * is being changed) before any changes can be made.
+ * Idea from util-linux chfn/chsh. --marekm
+ */
+
+ if (!amroot && getdef_bool("CHFN_AUTH"))
+ passwd_check(pw->pw_name, pw->pw_passwd, "chfn");
+
+ /*
+ * Now get the full name. It is the first comma separated field
+ * in the GECOS field.
+ */
+
+ STRFCPY(old_gecos, pw->pw_gecos);
+ cp = copy_field (old_gecos, fflg ? (char *) 0:fullnm, slop);
+
+ /*
+ * Now get the room number. It is the next comma separated field,
+ * if there is indeed one.
+ */
+
+ if (cp)
+ cp = copy_field (cp, rflg ? (char *) 0:roomno, slop);
+
+ /*
+ * Now get the work phone number. It is the third field.
+ */
+
+ if (cp)
+ cp = copy_field (cp, wflg ? (char *) 0:workph, slop);
+
+ /*
+ * Now get the home phone number. It is the fourth field.
+ */
+
+ if (cp)
+ cp = copy_field (cp, hflg ? (char *) 0:homeph, slop);
+
+ /*
+ * Anything left over is "slop".
+ */
+
+ if (cp && !oflg) {
+ if (slop[0])
+ strcat (slop, ",");
+
+ strcat (slop, cp);
+ }
+
+ /*
+ * If none of the fields were changed from the command line,
+ * let the user interactively change them.
+ */
+
+ if (!fflg && !rflg && !wflg && !hflg && !oflg) {
+ printf(_("Changing the user information for %s\n"), user);
+ new_fields();
+ }
+
+ /*
+ * Check all of the fields for valid information
+ */
+
+ if (valid_field(fullnm, ":,=")) {
+ fprintf(stderr, _("%s: invalid name: \"%s\"\n"), Prog, fullnm);
+ closelog();
+ exit(1);
+ }
+ if (valid_field(roomno, ":,=")) {
+ fprintf(stderr, _("%s: invalid room number: \"%s\"\n"), Prog, roomno);
+ closelog();
+ exit(1);
+ }
+ if (valid_field(workph, ":,=")) {
+ fprintf(stderr, _("%s: invalid work phone: \"%s\"\n"), Prog, workph);
+ closelog();
+ exit(1);
+ }
+ if (valid_field (homeph, ":,=")) {
+ fprintf(stderr, _("%s: invalid home phone: \"%s\"\n"), Prog, homeph);
+ closelog();
+ exit(1);
+ }
+ if (valid_field(slop, ":")) {
+ fprintf(stderr, _("%s: \"%s\" contains illegal characters\n"), Prog, slop);
+ closelog();
+ exit(1);
+ }
+
+ /*
+ * Build the new GECOS field by plastering all the pieces together,
+ * if they will fit ...
+ */
+
+ if (strlen(fullnm) + strlen(roomno) + strlen(workph) +
+ strlen(homeph) + strlen(slop) > (unsigned int) 80) {
+ fprintf(stderr, _("%s: fields too long\n"), Prog);
+ closelog();
+ exit(1);
+ }
+ snprintf(new_gecos, sizeof new_gecos, "%s,%s,%s,%s%s%s",
+ fullnm, roomno, workph, homeph, slop[0] ? "," : "", slop);
+
+ /*
+ * Before going any further, raise the ulimit to prevent
+ * colliding into a lowered ulimit, and set the real UID
+ * to root to protect against unexpected signals. Any
+ * keyboard signals are set to be ignored.
+ */
+
+ if (setuid(0)) {
+ fprintf(stderr, _("Cannot change ID to root.\n"));
+ SYSLOG((LOG_ERR, NOTROOT2));
+ closelog();
+ exit(1);
+ }
+ pwd_init();
+
+ /*
+ * The passwd entry is now ready to be committed back to
+ * the password file. Get a lock on the file and open it.
+ */
+
+ if (!pw_lock()) {
+ fprintf(stderr, _("Cannot lock the password file; try again later.\n"));
+ SYSLOG((LOG_WARN, PWDBUSY2));
+ closelog();
+ exit(1);
+ }
+ if (!pw_open(O_RDWR)) {
+ fprintf(stderr, _("Cannot open the password file.\n"));
+ pw_unlock();
+ SYSLOG((LOG_ERR, OPNERROR2));
+ closelog();
+ exit(1);
+ }
+
+ /*
+ * Get the entry to update using pw_locate() - we want the real
+ * one from /etc/passwd, not the one from getpwnam() which could
+ * contain the shadow password if (despite the warnings) someone
+ * enables AUTOSHADOW (or SHADOW_COMPAT in libc). --marekm
+ */
+ pw = pw_locate(user);
+ if (!pw) {
+ pw_unlock();
+ fprintf(stderr,
+ _("%s: %s not found in /etc/passwd\n"), Prog, user);
+ exit(1);
+ }
+
+ /*
+ * Make a copy of the entry, then change the gecos field. The other
+ * fields remain unchanged.
+ */
+ pwent = *pw;
+ pwent.pw_gecos = new_gecos;
+
+ /*
+ * Update the passwd file entry. If there is a DBM file,
+ * update that entry as well.
+ */
+
+ if (!pw_update(&pwent)) {
+ fprintf(stderr, _("Error updating the password entry.\n"));
+ pw_unlock();
+ SYSLOG((LOG_ERR, UPDERROR2));
+ closelog();
+ exit(1);
+ }
+#ifdef NDBM
+ if (pw_dbm_present() && !pw_dbm_update(&pwent)) {
+ fprintf(stderr, _("Error updating the DBM password entry.\n"));
+ pw_unlock ();
+ SYSLOG((LOG_ERR, DBMERROR2));
+ closelog();
+ exit(1);
+ }
+ endpwent();
+#endif
+
+ /*
+ * Changes have all been made, so commit them and unlock the
+ * file.
+ */
+
+ if (!pw_close()) {
+ fprintf(stderr, _("Cannot commit password file changes.\n"));
+ pw_unlock();
+ SYSLOG((LOG_ERR, CLSERROR2));
+ closelog();
+ exit(1);
+ }
+ if (!pw_unlock()) {
+ fprintf(stderr, _("Cannot unlock the password file.\n"));
+ SYSLOG((LOG_ERR, UNLKERROR2));
+ closelog();
+ exit(1);
+ }
+ SYSLOG((LOG_INFO, CHGGECOS, user));
+ closelog();
+ exit (0);
+}
diff --git a/current/src/chpasswd.c b/current/src/chpasswd.c
new file mode 100644
index 00000000..dc46498f
--- /dev/null
+++ b/current/src/chpasswd.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * chpasswd - update passwords in batch
+ *
+ * chpasswd reads standard input for a list of colon separated
+ * user names and new passwords. the appropriate password
+ * files are updated to reflect the changes. because the
+ * changes are made in a batch fashion, the user must run
+ * the mkpasswd command after this command terminates since
+ * no password updates occur until the very end.
+ *
+ * 1997/07/29: Modified to take "-e" argument which specifies that
+ * the passwords have already been encrypted.
+ * -- Jay Soffian <jay@lw.net>
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: chpasswd.c,v 1.10 2000/08/26 18:27:18 marekm Exp $")
+
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include <fcntl.h>
+#include "pwio.h"
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+
+static char *Prog;
+static int eflg = 0;
+#ifdef SHADOWPWD
+static int is_shadow_pwd;
+#endif
+
+extern char *l64a();
+
+/* local function prototypes */
+static void usage(void);
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: %s [-e]\n"), Prog);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[BUFSIZ];
+ char *name;
+ char *newpwd;
+ char *cp;
+#ifdef SHADOWPWD
+ const struct spwd *sp;
+ struct spwd newsp;
+#endif
+ const struct passwd *pw;
+ struct passwd newpw;
+#ifdef ATT_AGE
+ char newage[5];
+#endif
+ int errors = 0;
+ int line = 0;
+ long now = time ((long *) 0) / (24L*3600L);
+ int ok;
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* XXX - use getopt() */
+ if (!(argc == 1 || (argc == 2 && !strcmp(argv[1], "-e"))))
+ usage();
+ if (argc == 2)
+ eflg = 1;
+
+ /*
+ * Lock the password file and open it for reading. This will
+ * bring all of the entries into memory where they may be
+ * updated.
+ */
+
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: can't lock password file\n"), Prog);
+ exit(1);
+ }
+ if (! pw_open (O_RDWR)) {
+ fprintf(stderr, _("%s: can't open password file\n"), Prog);
+ pw_unlock();
+ exit(1);
+ }
+#ifdef SHADOWPWD
+ is_shadow_pwd = spw_file_present();
+ if (is_shadow_pwd) {
+ if (!spw_lock()) {
+ fprintf(stderr, _("%s: can't lock shadow file\n"), Prog);
+ pw_unlock();
+ exit(1);
+ }
+ if (!spw_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow file\n"), Prog);
+ pw_unlock();
+ spw_unlock();
+ exit(1);
+ }
+ }
+#endif
+
+ /*
+ * Read each line, separating the user name from the password.
+ * The password entry for each user will be looked up in the
+ * appropriate file (shadow or passwd) and the password changed.
+ * For shadow files the last change date is set directly, for
+ * passwd files the last change date is set in the age only if
+ * aging information is present.
+ */
+
+ while (fgets (buf, sizeof buf, stdin) != (char *) 0) {
+ line++;
+ if ((cp = strrchr (buf, '\n'))) {
+ *cp = '\0';
+ } else {
+ fprintf(stderr, _("%s: line %d: line too long\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+
+ /*
+ * The username is the first field. It is separated
+ * from the password with a ":" character which is
+ * replaced with a NUL to give the new password. The
+ * new password will then be encrypted in the normal
+ * fashion with a new salt generated, unless the '-e'
+ * is given, in which case it is assumed to already be
+ * encrypted.
+ */
+
+ name = buf;
+ if ((cp = strchr (name, ':'))) {
+ *cp++ = '\0';
+ } else {
+ fprintf(stderr, _("%s: line %d: missing new password\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+ newpwd = cp;
+ if (!eflg)
+ cp = pw_encrypt(newpwd, crypt_make_salt());
+
+ /*
+ * Get the password file entry for this user. The user
+ * must already exist.
+ */
+
+ pw = pw_locate(name);
+ if (!pw) {
+ fprintf (stderr, _("%s: line %d: unknown user %s\n"),
+ Prog, line, name);
+ errors++;
+ continue;
+ }
+
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ sp = spw_locate(name);
+ else
+ sp = NULL;
+#endif
+
+ /*
+ * The freshly encrypted new password is merged into
+ * the user's password file entry and the last password
+ * change date is set to the current date.
+ */
+
+#ifdef SHADOWPWD
+ if (sp) {
+ newsp = *sp;
+ newsp.sp_pwdp = cp;
+ newsp.sp_lstchg = now;
+ } else
+#endif
+ {
+ newpw = *pw;
+ newpw.pw_passwd = cp;
+#ifdef ATT_AGE
+ if (newpw.pw_age[0]) {
+ strcpy(newage, newpw.pw_age);
+ strcpy(newage + 2, l64a(now / 7));
+ newpw.pw_age = newage;
+ }
+#endif
+ }
+
+ /*
+ * The updated password file entry is then put back
+ * and will be written to the password file later, after
+ * all the other entries have been updated as well.
+ */
+
+#ifdef SHADOWPWD
+ if (sp)
+ ok = spw_update(&newsp);
+ else
+#endif
+ ok = pw_update(&newpw);
+
+ if (!ok) {
+ fprintf(stderr, _("%s: line %d: cannot update password entry\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+ }
+
+ /*
+ * Any detected errors will cause the entire set of changes
+ * to be aborted. Unlocking the password file will cause
+ * all of the changes to be ignored. Otherwise the file is
+ * closed, causing the changes to be written out all at
+ * once, and then unlocked afterwards.
+ */
+
+ if (errors) {
+ fprintf(stderr, _("%s: error detected, changes ignored\n"), Prog);
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ spw_unlock();
+#endif
+ pw_unlock();
+ exit(1);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd) {
+ if (!spw_close()) {
+ fprintf(stderr, _("%s: error updating shadow file\n"), Prog);
+ pw_unlock();
+ exit(1);
+ }
+ spw_unlock();
+ }
+#endif
+ if (!pw_close()) {
+ fprintf(stderr, _("%s: error updating password file\n"), Prog);
+ exit(1);
+ }
+ pw_unlock();
+
+ return (0);
+}
diff --git a/current/src/chsh.c b/current/src/chsh.c
new file mode 100644
index 00000000..fa4a7273
--- /dev/null
+++ b/current/src/chsh.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: chsh.c,v 1.17 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#include <pwd.h>
+#include "pwio.h"
+#include "getdef.h"
+#include "pwauth.h"
+
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+#ifdef USE_PAM
+#include "pam_defs.h"
+#endif
+
+#ifndef SHELLS_FILE
+#define SHELLS_FILE "/etc/shells"
+#endif
+
+/*
+ * Global variables.
+ */
+
+static char *Prog; /* Program name */
+static int amroot; /* Real UID is root */
+static char loginsh[BUFSIZ]; /* Name of new login shell */
+
+/*
+ * External identifiers
+ */
+
+extern int optind;
+extern char *optarg;
+#ifdef NDBM
+extern int pw_dbm_mode;
+#endif
+
+/*
+ * #defines for messages. This facilitates foreign language conversion
+ * since all messages are defined right here.
+ */
+
+#define WRONGPWD2 "incorrect password for `%s'"
+#define NOPERM2 "can't change shell for `%s'\n"
+#define PWDBUSY2 "can't lock /etc/passwd\n"
+#define OPNERROR2 "can't open /etc/passwd\n"
+#define UPDERROR2 "error updating passwd entry\n"
+#define DBMERROR2 "error updating DBM passwd entry.\n"
+#define NOTROOT2 "can't setuid(0).\n"
+#define CLSERROR2 "can't rewrite /etc/passwd.\n"
+#define UNLKERROR2 "can't unlock /etc/passwd.\n"
+#define CHGSHELL "changed user `%s' shell to `%s'\n"
+
+/* local function prototypes */
+static void usage(void);
+static void new_fields(void);
+static int restricted_shell(const char *);
+
+/*
+ * usage - print command line syntax and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("Usage: %s [ -s shell ] [ name ]\n"), Prog);
+ exit(1);
+}
+
+/*
+ * new_fields - change the user's login shell information interactively
+ *
+ * prompt the user for the login shell and change it according to the
+ * response, or leave it alone if nothing was entered.
+ */
+
+static void
+new_fields(void)
+{
+ printf(_("Enter the new value, or press return for the default\n"));
+ change_field(loginsh, sizeof loginsh, _("Login Shell"));
+}
+
+/*
+ * restricted_shell - return true if the named shell begins with 'r' or 'R'
+ *
+ * If the first letter of the filename is 'r' or 'R', the shell is
+ * considered to be restricted.
+ */
+
+static int
+restricted_shell(const char *sh)
+{
+#if 0
+ char *cp = Basename((char *) sh);
+ return *cp == 'r' || *cp == 'R';
+#else
+ /*
+ * Shells not listed in /etc/shells are considered to be
+ * restricted. Changed this to avoid confusion with "rc"
+ * (the plan9 shell - not restricted despite the name
+ * starting with 'r'). --marekm
+ */
+ return !check_shell(sh);
+#endif
+}
+
+
+/*
+ * chsh - this command controls changes to the user's shell
+ *
+ * The only supported option is -s which permits the
+ * the login shell to be set from the command line.
+ */
+
+int
+main(int argc, char **argv)
+{
+ char *user; /* User name */
+ int flag; /* Current command line flag */
+ int sflg = 0; /* -s - set shell from command line */
+ const struct passwd *pw; /* Password entry from /etc/passwd */
+ struct passwd pwent; /* New password entry */
+
+ sanitize_env();
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /*
+ * This command behaves different for root and non-root
+ * users.
+ */
+
+ amroot = getuid () == 0;
+#ifdef NDBM
+ pw_dbm_mode = O_RDWR;
+#endif
+
+ /*
+ * Get the program name. The program name is used as a
+ * prefix to most error messages.
+ */
+
+ Prog = Basename(argv[0]);
+
+ OPENLOG("chsh");
+
+ /*
+ * There is only one option, but use getopt() anyway to
+ * keep things consistent.
+ */
+
+ while ((flag = getopt (argc, argv, "s:")) != EOF) {
+ switch (flag) {
+ case 's':
+ sflg++;
+ STRFCPY(loginsh, optarg);
+ break;
+ default:
+ usage ();
+ }
+ }
+
+ /*
+ * There should be only one remaining argument at most
+ * and it should be the user's name.
+ */
+
+ if (argc > optind + 1)
+ usage ();
+
+ /*
+ * Get the name of the user to check. It is either
+ * the command line name, or the name getlogin()
+ * returns.
+ */
+
+ if (optind < argc) {
+ user = argv[optind];
+ pw = getpwnam(user);
+ if (!pw) {
+ fprintf(stderr,
+ _("%s: Unknown user %s\n"),
+ Prog, user);
+ exit(1);
+ }
+ } else {
+ pw = get_my_pwent();
+ if (!pw) {
+ fprintf(stderr,
+ _("%s: Cannot determine your user name.\n"),
+ Prog);
+ exit(1);
+ }
+ user = xstrdup(pw->pw_name);
+ }
+
+#ifdef USE_NIS
+ /*
+ * Now we make sure this is a LOCAL password entry for
+ * this user ...
+ */
+
+ if (__ispwNIS ()) {
+ char *nis_domain;
+ char *nis_master;
+
+ fprintf(stderr,
+ _("%s: cannot change user `%s' on NIS client.\n"),
+ Prog, user);
+
+ if (! yp_get_default_domain (&nis_domain) &&
+ ! yp_master (nis_domain, "passwd.byname",
+ &nis_master)) {
+ fprintf(stderr,
+ _("%s: `%s' is the NIS master for this client.\n"),
+ Prog, nis_master);
+ }
+ exit (1);
+ }
+#endif
+
+ /*
+ * Non-privileged users are only allowed to change the
+ * shell if the UID of the user matches the current
+ * real UID.
+ */
+
+ if (! amroot && pw->pw_uid != getuid()) {
+ SYSLOG((LOG_WARN, NOPERM2, user));
+ closelog();
+ fprintf(stderr, _("You may not change the shell for %s.\n"),
+ user);
+ exit(1);
+ }
+
+ /*
+ * Non-privileged users are only allowed to change the
+ * shell if it is not a restricted one.
+ */
+
+ if (! amroot && restricted_shell(pw->pw_shell)) {
+ SYSLOG((LOG_WARN, NOPERM2, user));
+ closelog();
+ fprintf(stderr, _("You may not change the shell for %s.\n"),
+ user);
+ exit(1);
+ }
+
+ /*
+ * Non-privileged users are optionally authenticated
+ * (must enter the password of the user whose information
+ * is being changed) before any changes can be made.
+ * Idea from util-linux chfn/chsh. --marekm
+ */
+
+ if (!amroot && getdef_bool("CHFN_AUTH"))
+ passwd_check(pw->pw_name, pw->pw_passwd, "chsh");
+
+ /*
+ * Now get the login shell. Either get it from the password
+ * file, or use the value from the command line.
+ */
+
+ if (! sflg)
+ STRFCPY(loginsh, pw->pw_shell);
+
+ /*
+ * If the login shell was not set on the command line,
+ * let the user interactively change it.
+ */
+
+ if (! sflg) {
+ printf(_("Changing the login shell for %s\n"), user);
+ new_fields();
+ }
+
+ /*
+ * Check all of the fields for valid information. The shell
+ * field may not contain any illegal characters. Non-privileged
+ * users are restricted to using the shells in /etc/shells.
+ * The shell must be executable by the user.
+ */
+
+ if (valid_field (loginsh, ":,=")) {
+ fprintf(stderr, _("%s: Invalid entry: %s\n"), Prog, loginsh);
+ closelog();
+ exit(1);
+ }
+ if (!amroot && (!check_shell(loginsh) || access(loginsh, X_OK) != 0)) {
+ fprintf(stderr, _("%s is an invalid shell.\n"), loginsh);
+ closelog();
+ exit(1);
+ }
+
+ /*
+ * Before going any further, raise the ulimit to prevent
+ * colliding into a lowered ulimit, and set the real UID
+ * to root to protect against unexpected signals. Any
+ * keyboard signals are set to be ignored.
+ */
+
+ if (setuid(0)) {
+ SYSLOG((LOG_ERR, NOTROOT2));
+ closelog();
+ fprintf (stderr, _("Cannot change ID to root.\n"));
+ exit(1);
+ }
+ pwd_init();
+
+ /*
+ * The passwd entry is now ready to be committed back to
+ * the password file. Get a lock on the file and open it.
+ */
+
+ if (!pw_lock()) {
+ SYSLOG((LOG_WARN, PWDBUSY2));
+ closelog();
+ fprintf(stderr,
+ _("Cannot lock the password file; try again later.\n"));
+ exit(1);
+ }
+ if (! pw_open (O_RDWR)) {
+ SYSLOG((LOG_ERR, OPNERROR2));
+ closelog();
+ fprintf(stderr, _("Cannot open the password file.\n"));
+ pw_unlock();
+ exit(1);
+ }
+
+ /*
+ * Get the entry to update using pw_locate() - we want the real
+ * one from /etc/passwd, not the one from getpwnam() which could
+ * contain the shadow password if (despite the warnings) someone
+ * enables AUTOSHADOW (or SHADOW_COMPAT in libc). --marekm
+ */
+ pw = pw_locate(user);
+ if (!pw) {
+ pw_unlock();
+ fprintf(stderr,
+ _("%s: %s not found in /etc/passwd\n"), Prog, user);
+ exit(1);
+ }
+
+ /*
+ * Make a copy of the entry, then change the shell field. The other
+ * fields remain unchanged.
+ */
+ pwent = *pw;
+ pwent.pw_shell = loginsh;
+
+ /*
+ * Update the passwd file entry. If there is a DBM file,
+ * update that entry as well.
+ */
+
+ if (!pw_update(&pwent)) {
+ SYSLOG((LOG_ERR, UPDERROR2));
+ closelog();
+ fprintf(stderr, _("Error updating the password entry.\n"));
+ pw_unlock();
+ exit(1);
+ }
+#ifdef NDBM
+ if (pw_dbm_present() && ! pw_dbm_update (&pwent)) {
+ SYSLOG((LOG_ERR, DBMERROR2));
+ closelog();
+ fprintf (stderr, _("Error updating the DBM password entry.\n"));
+ pw_unlock();
+ exit(1);
+ }
+ endpwent();
+#endif
+
+ /*
+ * Changes have all been made, so commit them and unlock the
+ * file.
+ */
+
+ if (!pw_close()) {
+ SYSLOG((LOG_ERR, CLSERROR2));
+ closelog();
+ fprintf(stderr, _("Cannot commit password file changes.\n"));
+ pw_unlock();
+ exit(1);
+ }
+ if (!pw_unlock()) {
+ SYSLOG((LOG_ERR, UNLKERROR2));
+ closelog();
+ fprintf(stderr, _("Cannot unlock the password file.\n"));
+ exit(1);
+ }
+ SYSLOG((LOG_INFO, CHGSHELL, user, loginsh));
+ closelog();
+ exit (0);
+}
diff --git a/current/src/dpasswd.c b/current/src/dpasswd.c
new file mode 100644
index 00000000..6de5ea20
--- /dev/null
+++ b/current/src/dpasswd.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright 1990 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: dpasswd.c,v 1.12 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <signal.h>
+#include <fcntl.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "dialup.h"
+
+#define DTMP "/etc/d_passwd.tmp"
+
+/*
+ * Prompts and messages go here.
+ */
+
+#define DIALCHG "changed password for %s\n"
+#define DIALADD "added password for %s\n"
+#define DIALREM "removed password for %s\n"
+
+static int aflg = 0;
+static int dflg = 0;
+static char *Prog;
+
+extern int optind;
+extern char *optarg;
+
+extern char *getpass();
+
+/* local function prototypes */
+static void usage(void);
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("Usage: %s [ -(a|d) ] shell\n"), Prog);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct dialup *dial;
+ struct dialup dent;
+ struct stat sb;
+ FILE *fp;
+ char *sh = 0;
+ char *cp;
+ char pass[BUFSIZ];
+ int fd;
+ int found = 0;
+ int opt;
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+ while ((opt = getopt (argc, argv, "a:d:")) != EOF) {
+ switch (opt) {
+ case 'a':
+ aflg++;
+ sh = optarg;
+ break;
+ case 'd':
+ dflg++;
+ sh = optarg;
+ break;
+ default:
+ usage ();
+ }
+ }
+ if (! aflg && ! dflg)
+ aflg++;
+
+ if (! sh) {
+ if (optind >= argc)
+ usage ();
+ else
+ sh = argv[optind];
+ }
+ if (aflg + dflg != 1)
+ usage ();
+
+ /*
+ * Add a new shell to the password file, or update an existing
+ * entry. Begin by getting an encrypted password for this
+ * shell.
+ */
+
+ if (aflg) {
+ int tries = 3;
+
+ dent.du_shell = sh;
+ dent.du_passwd = ""; /* XXX warning: const */
+
+again:
+ if (! (cp = getpass(_("Shell password: "))))
+ exit (1);
+
+ STRFCPY(pass, cp);
+ strzero(cp);
+
+ if (! (cp = getpass(_("re-enter Shell password: "))))
+ exit (1);
+
+ if (strcmp (pass, cp)) {
+ strzero(pass);
+ strzero(cp);
+ fprintf(stderr,
+ _("%s: Passwords do not match, try again.\n"),
+ Prog);
+
+ if (--tries)
+ goto again;
+
+ exit(1);
+ }
+ strzero(cp);
+ dent.du_passwd = pw_encrypt(pass, crypt_make_salt());
+ strzero(pass);
+ }
+
+ /*
+ * Create the temporary file for the updated dialup password
+ * information to be placed into. Turn it into a (FILE *)
+ * for use by putduent().
+ */
+
+ if ((fd = open (DTMP, O_CREAT|O_EXCL|O_RDWR, 0600)) < 0) {
+ snprintf(pass, sizeof pass, _("%s: can't create %s"), Prog, DTMP);
+ perror (pass);
+ exit (1);
+ }
+ if (! (fp = fdopen (fd, "r+"))) {
+ snprintf(pass, sizeof pass, _("%s: can't open %s"), Prog, DTMP);
+ perror (pass);
+ unlink (DTMP);
+ exit (1);
+ }
+
+ /*
+ * Scan the dialup password file for the named entry,
+ * copying out other entries along the way. Copying
+ * stops when a match is found or the file runs out.
+ */
+
+ while ((dial = getduent ())) {
+ if (strcmp (dial->du_shell, sh) == 0) {
+ found = 1;
+ break;
+ }
+ if (putduent (dial, fp))
+ goto failure;
+ }
+
+ /*
+ * To delete the entry, just don't copy it. To update
+ * the entry, output the modified version - works with
+ * new entries as well.
+ */
+
+ if (dflg && ! found) {
+ fprintf(stderr, _("%s: Shell %s not found.\n"), Prog, sh);
+ goto failure;
+ }
+ if (aflg)
+ if (putduent (&dent, fp))
+ goto failure;
+
+ /*
+ * Now copy out the remaining entries. Flush and close the
+ * new file before doing anything nasty to the existing
+ * file.
+ */
+
+
+ while ((dial = getduent ()))
+ if (putduent (dial, fp))
+ goto failure;
+
+ if (fflush (fp))
+ goto failure;
+
+ fclose (fp);
+
+ /*
+ * If the original file did not exist, we must create a new
+ * file with owner "root" and mode 400. Otherwise we copy
+ * the modes from the existing file to the new file.
+ *
+ * After this is done the new file will replace the old file.
+ */
+
+ pwd_init();
+
+ if (! stat (DIALPWD, &sb)) {
+ chown (DTMP, sb.st_uid, sb.st_gid);
+ chmod (DTMP, sb.st_mode);
+ unlink (DIALPWD);
+ } else {
+ chown (DTMP, 0, 0);
+ chmod (DTMP, 0400);
+ }
+ if (! link (DTMP, DIALPWD))
+ unlink (DTMP);
+
+ if (aflg && ! found)
+ SYSLOG((LOG_INFO, DIALADD, sh));
+ else if (aflg && found)
+ SYSLOG((LOG_INFO, DIALCHG, sh));
+ else if (dflg)
+ SYSLOG((LOG_INFO, DIALREM, sh));
+
+ closelog();
+ sync ();
+ exit (0);
+
+failure:
+ unlink (DTMP);
+ closelog();
+ exit (1);
+}
diff --git a/current/src/expiry.c b/current/src/expiry.c
new file mode 100644
index 00000000..b8d09b50
--- /dev/null
+++ b/current/src/expiry.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: expiry.c,v 1.9 2000/08/26 18:27:18 marekm Exp $")
+
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+
+#ifndef AGING
+#if defined(HAVE_USERSEC_H) || defined(SHADOWPWD)
+#define AGING 1
+#endif
+#endif
+
+
+#if !defined(SHADOWPWD) && !defined(AGING) /*{*/
+
+/*
+ * Not much to do here ...
+ */
+
+int
+main(int argc, char **argv)
+{
+ exit (0);
+}
+
+#else /*} AGING || SHADOWPWD {*/
+
+/* local function prototypes */
+static RETSIGTYPE catch(int);
+static void usage(void);
+
+/*
+ * catch - signal catcher
+ */
+
+static RETSIGTYPE
+catch(int sig)
+{
+ exit (10);
+}
+
+/*
+ * usage - print syntax message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("Usage: expiry { -f | -c }\n"));
+ exit(10);
+}
+
+/*
+ * expiry - check and enforce password expiration policy
+ *
+ * expiry checks (-c) the current password expiraction and
+ * forces (-f) changes when required. It is callable as a
+ * normal user command.
+ */
+
+int
+main(int argc, char **argv)
+{
+ struct passwd *pwd;
+#ifdef SHADOWPWD
+ struct spwd *spwd;
+#endif
+ char *Prog = argv[0];
+
+ sanitize_env();
+
+ /*
+ * Start by disabling all of the keyboard signals.
+ */
+
+ signal (SIGHUP, catch);
+ signal (SIGINT, catch);
+ signal (SIGQUIT, catch);
+#ifdef SIGTSTP
+ signal (SIGTSTP, catch);
+#endif
+
+ /*
+ * expiry takes one of two arguments. The default action
+ * is to give the usage message.
+ */
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc != 2 || (strcmp (argv[1], "-f") && strcmp (argv[1], "-c")))
+ usage ();
+
+#if 0 /* could be setgid shadow with /etc/shadow mode 0640 */
+ /*
+ * Make sure I am root. Can't open /etc/shadow without root
+ * authority.
+ */
+
+ if (geteuid () != 0) {
+ fprintf(stderr, _("%s: WARNING! Must be set-UID root!\n"),
+ argv[0]);
+ exit(10);
+ }
+#endif
+
+ /*
+ * Get user entries for /etc/passwd and /etc/shadow
+ */
+
+ if (!(pwd = get_my_pwent())) {
+ fprintf(stderr, _("%s: unknown user\n"), Prog);
+ exit(10);
+ }
+#ifdef SHADOWPWD
+ spwd = getspnam(pwd->pw_name);
+#endif
+
+ /*
+ * If checking accounts, use agecheck() function.
+ */
+
+ if (strcmp (argv[1], "-c") == 0) {
+
+ /*
+ * Print out number of days until expiration.
+ */
+
+#ifdef SHADOWPWD
+ agecheck (pwd, spwd);
+#else
+ agecheck (pwd);
+#endif
+
+ /*
+ * Exit with status indicating state of account --
+ */
+
+#ifdef SHADOWPWD
+ exit (isexpired (pwd, spwd));
+#else
+ exit (isexpired (pwd));
+#endif
+ }
+
+ /*
+ * If forcing password change, use expire() function.
+ */
+
+ if (strcmp (argv[1], "-f") == 0) {
+
+ /*
+ * Just call expire(). It will force the change
+ * or give a message indicating what to do. And
+ * it doesn't return at all unless the account
+ * is unexpired.
+ */
+
+#ifdef SHADOWPWD
+ expire (pwd, spwd);
+#else
+ expire (pwd);
+#endif
+ exit (0);
+ }
+
+ /*
+ * Can't get here ...
+ */
+
+ usage ();
+ exit (1);
+}
+#endif /*}*/
diff --git a/current/src/faillog.c b/current/src/faillog.c
new file mode 100644
index 00000000..beb418ba
--- /dev/null
+++ b/current/src/faillog.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright 1989 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: faillog.c,v 1.10 2000/08/26 18:27:18 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <time.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "faillog.h"
+
+static char *Prog; /* program name */
+static FILE *fail; /* failure file stream */
+static uid_t user; /* one single user, specified on command line */
+static int days; /* number of days to consider for print command */
+static time_t seconds; /* that number of days in seconds */
+
+static int
+ aflg = 0, /* set if all users are to be printed always */
+ uflg = 0, /* set if user is a valid user id */
+ tflg = 0; /* print is restricted to most recent days */
+
+static struct stat statbuf; /* fstat buffer for file size */
+
+#if !defined(UNISTD_H) && !defined(STDLIB_H)
+extern char *optarg;
+#endif
+
+#define NOW (time((time_t *) 0))
+
+/* local function prototypes */
+static void usage(void);
+static void print(void);
+static void print_one(const struct faillog *, uid_t);
+static void reset(void);
+static int reset_one(uid_t);
+static void setmax(int);
+static void setmax_one(uid_t, int);
+static void set_locktime(long);
+static void set_locktime_one(uid_t, long);
+
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ _("usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"),
+ Prog);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c, anyflag = 0;
+ struct passwd *pwent;
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* try to open for read/write, if that fails - read only */
+
+ fail = fopen(FAILLOG_FILE, "r+");
+ if (!fail)
+ fail = fopen(FAILLOG_FILE, "r");
+ if (!fail) {
+ perror(FAILLOG_FILE);
+ exit(1);
+ }
+ while ((c = getopt(argc, argv, "al:m:pru:t:")) != EOF) {
+ switch (c) {
+ case 'a':
+ aflg++;
+ if (uflg)
+ usage();
+ break;
+ case 'l':
+ set_locktime((long) atoi(optarg));
+ anyflag++;
+ break;
+ case 'm':
+ setmax(atoi(optarg));
+ anyflag++;
+ break;
+ case 'p':
+ print();
+ anyflag++;
+ break;
+ case 'r':
+ reset();
+ anyflag++;
+ break;
+ case 'u':
+ if (aflg)
+ usage();
+
+ pwent = getpwnam(optarg);
+ if (!pwent) {
+ fprintf(stderr, _("Unknown User: %s\n"), optarg);
+ exit(1);
+ }
+ uflg++;
+ user = pwent->pw_uid;
+ break;
+ case 't':
+ days = atoi(optarg);
+ seconds = days * DAY;
+ tflg++;
+ break;
+ default:
+ usage();
+ }
+ }
+ /* no flags implies -a -p (= print information for all users) */
+ if (!(anyflag || aflg || tflg || uflg))
+ aflg++;
+ /* (-a or -t days or -u user) and no other flags implies -p
+ (= print information for selected users) */
+ if (!anyflag && (aflg || tflg || uflg))
+ print();
+ fclose(fail);
+ return 0;
+ /*NOTREACHED*/
+}
+
+static void
+print(void)
+{
+ uid_t uid;
+ off_t offset;
+ struct faillog faillog;
+
+ if (uflg) {
+ offset = user * sizeof faillog;
+ if (fstat(fileno(fail), &statbuf)) {
+ perror(FAILLOG_FILE);
+ return;
+ }
+ if (offset >= statbuf.st_size)
+ return;
+
+ fseek(fail, (off_t) user * sizeof faillog, SEEK_SET);
+ if (fread((char *) &faillog, sizeof faillog, 1, fail) == 1)
+ print_one(&faillog, user);
+ else
+ perror(FAILLOG_FILE);
+ } else {
+ for (uid = 0;
+ fread((char *) &faillog, sizeof faillog, 1, fail) == 1;
+ uid++) {
+
+ if (aflg == 0 && faillog.fail_cnt == 0)
+ continue;
+
+ if (aflg == 0 && tflg &&
+ NOW - faillog.fail_time > seconds)
+ continue;
+
+ if (aflg && faillog.fail_time == 0)
+ continue;
+
+ print_one(&faillog, uid);
+ }
+ }
+}
+
+static void
+print_one(const struct faillog *fl, uid_t uid)
+{
+ static int once;
+ char *cp;
+ struct tm *tm;
+ time_t now;
+ struct passwd *pwent;
+#ifdef HAVE_STRFTIME
+ char ptime[80];
+#endif
+
+ if (!once) {
+ printf(_("Username Failures Maximum Latest\n"));
+ once++;
+ }
+ pwent = getpwuid(uid);
+ time(&now);
+ tm = localtime(&fl->fail_time);
+#ifdef HAVE_STRFTIME
+ strftime(ptime, sizeof(ptime), "%a %b %e %H:%M:%S %z %Y",tm);
+ cp = ptime;
+#else
+ cp = asctime(tm);
+ cp[24] = '\0';
+#endif
+ if (pwent) {
+ printf("%-12s %4d %4d",
+ pwent->pw_name, fl->fail_cnt, fl->fail_max);
+ if (fl->fail_time) {
+ printf(_(" %s on %s"), cp, fl->fail_line);
+ if (fl->fail_locktime) {
+ if (fl->fail_time + fl->fail_locktime > now
+ && fl->fail_cnt)
+ printf(_(" [%lds left]"),
+ fl->fail_time + fl->fail_locktime - now);
+ else
+ printf(_(" [%lds lock]"), fl->fail_locktime);
+ }
+ }
+ putchar('\n');
+ }
+}
+
+static void
+reset(void)
+{
+ uid_t uid;
+
+ if (uflg)
+ reset_one(user);
+ else
+ for (uid = 0; reset_one(uid); uid++)
+ ;
+}
+
+static int
+reset_one(uid_t uid)
+{
+ off_t offset;
+ struct faillog faillog;
+
+ offset = uid * sizeof faillog;
+ if (fstat(fileno(fail), &statbuf)) {
+ perror(FAILLOG_FILE);
+ return 0;
+ }
+ if (offset >= statbuf.st_size)
+ return 0;
+
+ if (fseek(fail, offset, SEEK_SET) != 0) {
+ perror(FAILLOG_FILE);
+ return 0;
+ }
+ if (fread((char *) &faillog, sizeof faillog, 1, fail) != 1) {
+ if (!feof(fail))
+ perror(FAILLOG_FILE);
+
+ return 0;
+ }
+ if (faillog.fail_cnt == 0)
+ return 1; /* don't fill in no holes ... */
+
+ faillog.fail_cnt = 0;
+
+ if (fseek(fail, offset, SEEK_SET) == 0
+ && fwrite((char *) &faillog, sizeof faillog, 1, fail) == 1) {
+ fflush(fail);
+ return 1;
+ } else {
+ perror(FAILLOG_FILE);
+ }
+ return 0;
+}
+
+static void
+setmax(int max)
+{
+ struct passwd *pwent;
+
+ if (uflg) {
+ setmax_one(user, max);
+ } else {
+ setpwent();
+ while ((pwent = getpwent()))
+ setmax_one(pwent->pw_uid, max);
+ }
+}
+
+static void
+setmax_one(uid_t uid, int max)
+{
+ off_t offset;
+ struct faillog faillog;
+
+ offset = uid * sizeof faillog;
+
+ if (fseek(fail, offset, SEEK_SET) != 0) {
+ perror(FAILLOG_FILE);
+ return;
+ }
+ if (fread((char *) &faillog, sizeof faillog, 1, fail) != 1) {
+ if (!feof(fail))
+ perror(FAILLOG_FILE);
+ memzero(&faillog, sizeof faillog);
+ }
+ faillog.fail_max = max;
+
+ if (fseek(fail, offset, SEEK_SET) == 0
+ && fwrite((char *) &faillog, sizeof faillog, 1, fail) == 1)
+ fflush(fail);
+ else
+ perror(FAILLOG_FILE);
+}
+
+/*
+ * XXX - this needs to be written properly some day, right now it is
+ * a quick cut-and-paste hack from the above two functions. --marekm
+ */
+static void
+set_locktime(long locktime)
+{
+ struct passwd *pwent;
+
+ if (uflg) {
+ set_locktime_one(user, locktime);
+ } else {
+ setpwent();
+ while ((pwent = getpwent()))
+ set_locktime_one(pwent->pw_uid, locktime);
+ }
+}
+
+static void
+set_locktime_one(uid_t uid, long locktime)
+{
+ off_t offset;
+ struct faillog faillog;
+
+ offset = uid * sizeof faillog;
+
+ if (fseek(fail, offset, SEEK_SET) != 0) {
+ perror(FAILLOG_FILE);
+ return;
+ }
+ if (fread((char *) &faillog, sizeof faillog, 1, fail) != 1) {
+ if (!feof(fail))
+ perror(FAILLOG_FILE);
+ memzero(&faillog, sizeof faillog);
+ }
+ faillog.fail_locktime = locktime;
+
+ if (fseek(fail, offset, SEEK_SET) == 0
+ && fwrite((char *) &faillog, sizeof faillog, 1, fail) == 1)
+ fflush(fail);
+ else
+ perror(FAILLOG_FILE);
+}
diff --git a/current/src/gpasswd.c b/current/src/gpasswd.c
new file mode 100644
index 00000000..d1bb023c
--- /dev/null
+++ b/current/src/gpasswd.c
@@ -0,0 +1,661 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: gpasswd.c,v 1.17 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include "groupio.h"
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+#endif
+
+static char *Prog;
+#ifdef SHADOWGRP
+static int is_shadowgrp;
+#endif
+
+static int
+ aflg = 0,
+ Aflg = 0,
+ dflg = 0,
+ Mflg = 0,
+ rflg = 0,
+ Rflg = 0;
+
+#ifndef RETRIES
+#define RETRIES 3
+#endif
+
+extern int optind;
+extern char *optarg;
+#ifdef NDBM
+#ifdef SHADOWGRP
+extern int sg_dbm_mode;
+#endif
+extern int gr_dbm_mode;
+#endif
+
+/* local function prototypes */
+static void usage(void);
+static RETSIGTYPE die(int);
+static int check_list(const char *);
+
+/*
+ * usage - display usage message
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: %s [-r|-R] group\n"), Prog);
+ fprintf(stderr, _(" %s [-a user] group\n"), Prog);
+ fprintf(stderr, _(" %s [-d user] group\n"), Prog);
+#ifdef SHADOWGRP
+ fprintf(stderr, _(" %s [-A user,...] [-M user,...] group\n"),
+ Prog);
+#else
+ fprintf(stderr, _(" %s [-M user,...] group\n"), Prog);
+#endif
+ exit (1);
+}
+
+/*
+ * die - set or reset termio modes.
+ *
+ * die() is called before processing begins. signal() is then
+ * called with die() as the signal handler. If signal later
+ * calls die() with a signal number, the terminal modes are
+ * then reset.
+ */
+
+static RETSIGTYPE
+die(int killed)
+{
+ static TERMIO sgtty;
+
+ if (killed)
+ STTY(0, &sgtty);
+ else
+ GTTY(0, &sgtty);
+
+ if (killed) {
+ putchar ('\n');
+ fflush (stdout);
+ exit (killed);
+ }
+}
+
+/*
+ * check_list - check a comma-separated list of user names for validity
+ *
+ * check_list scans a comma-separated list of user names and checks
+ * that each listed name exists.
+ */
+
+static int
+check_list(const char *users)
+{
+ const char *start, *end;
+ char username[32];
+ int errors = 0;
+ int len;
+
+ for (start = users; start && *start; start = end) {
+ if ((end = strchr (start, ','))) {
+ len = end - start;
+ end++;
+ } else {
+ len = strlen(start);
+ }
+
+ if (len > sizeof(username) - 1)
+ len = sizeof(username) - 1;
+ strncpy(username, start, len);
+ username[len] = '\0';
+
+ /*
+ * This user must exist.
+ */
+
+ if (!getpwnam(username)) {
+ fprintf(stderr, _("%s: unknown user %s\n"),
+ Prog, username);
+ errors++;
+ }
+ }
+ return errors;
+}
+
+
+static void
+failure(void)
+{
+ fprintf(stderr, _("Permission denied.\n"));
+ exit(1);
+ /*NOTREACHED*/
+}
+
+
+/*
+ * gpasswd - administer the /etc/group file
+ *
+ * -a user add user to the named group
+ * -d user remove user from the named group
+ * -r remove password from the named group
+ * -R restrict access to the named group
+ * -A user,... make list of users the administrative users
+ * -M user,... make list of users the group members
+ */
+
+int
+main(int argc, char **argv)
+{
+ int flag;
+ char *cp;
+ int amroot;
+ int retries;
+ struct group *gr = NULL;
+ struct group grent;
+ static char pass[BUFSIZ];
+#ifdef SHADOWGRP
+ struct sgrp *sg = NULL;
+ struct sgrp sgent;
+ char *admins = NULL;
+#endif
+ struct passwd *pw = NULL;
+ char *myname;
+ char *user = NULL;
+ char *group = NULL;
+ char *members = NULL;
+
+ sanitize_env();
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /*
+ * Make a note of whether or not this command was invoked
+ * by root. This will be used to bypass certain checks
+ * later on. Also, set the real user ID to match the
+ * effective user ID. This will prevent the invoker from
+ * issuing signals which would interfer with this command.
+ */
+
+ amroot = getuid () == 0;
+#ifdef NDBM
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif
+ gr_dbm_mode = O_RDWR;
+#endif
+
+ Prog = Basename(argv[0]);
+
+ OPENLOG("gpasswd");
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+#ifdef SHADOWGRP
+ is_shadowgrp = sgr_file_present();
+#endif
+ while ((flag = getopt (argc, argv, "a:d:grRA:M:")) != EOF) {
+ switch (flag) {
+ case 'a': /* add a user */
+ user = optarg;
+ if (!getpwnam(user)) {
+ fprintf(stderr, _("%s: unknown user %s\n"),
+ Prog, user);
+ exit(1);
+ }
+ aflg++;
+ break;
+#ifdef SHADOWGRP
+ case 'A':
+ if (!amroot)
+ failure();
+ if (!is_shadowgrp) {
+ fprintf(stderr,
+ _("%s: shadow group passwords required for -A\n"),
+ Prog);
+ exit(2);
+ }
+ admins = optarg;
+ if (check_list(admins))
+ exit(1);
+ Aflg++;
+ break;
+#endif
+ case 'd': /* delete a user */
+ dflg++;
+ user = optarg;
+ break;
+ case 'g': /* no-op from normal password */
+ break;
+ case 'M':
+ if (!amroot)
+ failure();
+ members = optarg;
+ if (check_list(members))
+ exit(1);
+ Mflg++;
+ break;
+ case 'r': /* remove group password */
+ rflg++;
+ break;
+ case 'R': /* restrict group password */
+ Rflg++;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ /*
+ * Make sure exclusive flags are exclusive
+ */
+
+ if (aflg + dflg + rflg + Rflg + (Aflg || Mflg) > 1)
+ usage ();
+
+ /*
+ * Determine the name of the user that invoked this command.
+ * This is really hit or miss because there are so many ways
+ * that command can be executed and so many ways to trip up
+ * the routines that report the user name.
+ */
+
+ pw = get_my_pwent();
+ if (!pw) {
+ fprintf(stderr, _("Who are you?\n"));
+ exit(1);
+ }
+ myname = xstrdup(pw->pw_name);
+
+ /*
+ * Get the name of the group that is being affected. The group
+ * entry will be completely replicated so it may be modified
+ * later on.
+ */
+
+ /*
+ * XXX - should get the entry using gr_locate() and modify
+ * that, getgrnam() could give us a NIS group. --marekm
+ */
+
+ if (! (group = argv[optind]))
+ usage ();
+
+ if (! (gr = getgrnam (group))) {
+ fprintf (stderr, _("unknown group: %s\n"), group);
+ exit (1);
+ }
+ grent = *gr;
+ grent.gr_name = xstrdup(gr->gr_name);
+ grent.gr_passwd = xstrdup(gr->gr_passwd);
+
+ grent.gr_mem = dup_list(gr->gr_mem);
+#ifdef SHADOWGRP
+ if ((sg = getsgnam (group))) {
+ sgent = *sg;
+ sgent.sg_name = xstrdup(sg->sg_name);
+ sgent.sg_passwd = xstrdup(sg->sg_passwd);
+
+ sgent.sg_mem = dup_list(sg->sg_mem);
+ sgent.sg_adm = dup_list(sg->sg_adm);
+ } else {
+ sgent.sg_name = xstrdup(group);
+ sgent.sg_passwd = grent.gr_passwd;
+ grent.gr_passwd = "!"; /* XXX warning: const */
+
+ sgent.sg_mem = dup_list(grent.gr_mem);
+
+ sgent.sg_adm = (char **) xmalloc(sizeof(char *) * 2);
+#ifdef FIRST_MEMBER_IS_ADMIN
+ if (sgent.sg_mem[0]) {
+ sgent.sg_adm[0] = xstrdup(sgent.sg_mem[0]);
+ sgent.sg_adm[1] = 0;
+ } else
+#endif
+ sgent.sg_adm[0] = 0;
+
+ sg = &sgent;
+ }
+
+ /*
+ * The policy here for changing a group is that 1) you must be
+ * root or 2). you must be listed as an administrative member.
+ * Administrative members can do anything to a group that the
+ * root user can.
+ */
+
+ if (!amroot && !is_on_list(sgent.sg_adm, myname))
+ failure();
+#else /* ! SHADOWGRP */
+
+#ifdef FIRST_MEMBER_IS_ADMIN
+ /*
+ * The policy here for changing a group is that 1) you must bes
+ * root or 2) you must be the first listed member of the group.
+ * The first listed member of a group can do anything to that
+ * group that the root user can. The rationale for this hack is
+ * that the FIRST user is probably the most important user in
+ * this entire group.
+ */
+
+ if (! amroot) {
+ if (grent.gr_mem[0] == (char *) 0)
+ failure();
+
+ if (strcmp(grent.gr_mem[0], myname) != 0)
+ failure();
+ }
+#else
+ /*
+ * This feature enabled by default could be a security problem
+ * when installed on existing systems where the first group
+ * member might be just a normal user... --marekm
+ */
+
+ if (!amroot)
+ failure();
+#endif
+
+#endif /* SHADOWGRP */
+
+ /*
+ * Removing a password is straight forward. Just set the
+ * password field to a "".
+ */
+
+ if (rflg) {
+ grent.gr_passwd = ""; /* XXX warning: const */
+#ifdef SHADOWGRP
+ sgent.sg_passwd = ""; /* XXX warning: const */
+#endif
+ SYSLOG((LOG_INFO, "remove password from group %s by %s\n", group, myname));
+ goto output;
+ } else if (Rflg) {
+ /*
+ * Same thing for restricting the group. Set the password
+ * field to "!".
+ */
+
+ grent.gr_passwd = "!"; /* XXX warning: const */
+#ifdef SHADOWGRP
+ sgent.sg_passwd = "!"; /* XXX warning: const */
+#endif
+ SYSLOG((LOG_INFO, "restrict access to group %s by %s\n", group, myname));
+ goto output;
+ }
+
+ /*
+ * Adding a member to a member list is pretty straightforward
+ * as well. Call the appropriate routine and split.
+ */
+
+ if (aflg) {
+ printf(_("Adding user %s to group %s\n"), user, group);
+ grent.gr_mem = add_list (grent.gr_mem, user);
+#ifdef SHADOWGRP
+ sgent.sg_mem = add_list (sgent.sg_mem, user);
+#endif
+ SYSLOG((LOG_INFO, "add member %s to group %s by %s\n", user, group, myname));
+ goto output;
+ }
+
+ /*
+ * Removing a member from the member list is the same deal
+ * as adding one, except the routine is different.
+ */
+
+ if (dflg) {
+ int removed = 0;
+
+ printf(_("Removing user %s from group %s\n"), user, group);
+
+ if (is_on_list(grent.gr_mem, user)) {
+ removed = 1;
+ grent.gr_mem = del_list (grent.gr_mem, user);
+ }
+#ifdef SHADOWGRP
+ if (is_on_list(sgent.sg_mem, user)) {
+ removed = 1;
+ sgent.sg_mem = del_list (sgent.sg_mem, user);
+ }
+#endif
+ if (! removed) {
+ fprintf(stderr, _("%s: unknown member %s\n"),
+ Prog, user);
+ exit (1);
+ }
+ SYSLOG((LOG_INFO, "remove member %s from group %s by %s\n",
+ user, group, myname));
+ goto output;
+ }
+
+#ifdef SHADOWGRP
+ /*
+ * Replacing the entire list of administators is simple. Check the
+ * list to make sure everyone is a real user. Then slap the new
+ * list in place.
+ */
+
+ if (Aflg) {
+ SYSLOG((LOG_INFO, "set administrators of %s to %s\n",
+ group, admins));
+ sgent.sg_adm = comma_to_list(admins);
+ if (!Mflg)
+ goto output;
+ }
+#endif
+
+ /*
+ * Replacing the entire list of members is simple. Check the list
+ * to make sure everyone is a real user. Then slap the new list
+ * in place.
+ */
+
+ if (Mflg) {
+ SYSLOG((LOG_INFO,"set members of %s to %s\n",group,members));
+#ifdef SHADOWGRP
+ sgent.sg_mem = comma_to_list(members);
+#endif
+ grent.gr_mem = comma_to_list(members);
+ goto output;
+ }
+
+ /*
+ * If the password is being changed, the input and output must
+ * both be a tty. The typical keyboard signals are caught
+ * so the termio modes can be restored.
+ */
+
+ if (! isatty (0) || ! isatty (1)) {
+ fprintf(stderr, _("%s: Not a tty\n"), Prog);
+ exit (1);
+ }
+
+ die (0); /* save tty modes */
+
+ signal (SIGHUP, die);
+ signal (SIGINT, die);
+ signal (SIGQUIT, die);
+ signal (SIGTERM, die);
+#ifdef SIGTSTP
+ signal (SIGTSTP, die);
+#endif
+
+ /*
+ * A new password is to be entered and it must be encrypted,
+ * etc. The password will be prompted for twice, and both
+ * entries must be identical. There is no need to validate
+ * the old password since the invoker is either the group
+ * owner, or root.
+ */
+
+ printf(_("Changing the password for group %s\n"), group);
+
+ for (retries = 0; retries < RETRIES; retries++) {
+ if (! (cp = getpass(_("New Password: "))))
+ exit (1);
+
+ STRFCPY(pass, cp);
+ strzero(cp);
+ if (! (cp = getpass (_("Re-enter new password: "))))
+ exit (1);
+
+ if (strcmp(pass, cp) == 0) {
+ strzero(cp);
+ break;
+ }
+
+ strzero(cp);
+ memzero(pass, sizeof pass);
+
+ if (retries + 1 < RETRIES)
+ puts(_("They don't match; try again"));
+ }
+
+ if (retries == RETRIES) {
+ fprintf(stderr, _("%s: Try again later\n"), Prog);
+ exit(1);
+ }
+
+ cp = pw_encrypt(pass, crypt_make_salt());
+ memzero(pass, sizeof pass);
+#ifdef SHADOWGRP
+ if (is_shadowgrp)
+ sgent.sg_passwd = cp;
+ else
+#endif
+ grent.gr_passwd = cp;
+ SYSLOG((LOG_INFO, "change the password for group %s by %s\n", group, myname));
+
+ /*
+ * This is the common arrival point to output the new group
+ * file. The freshly crafted entry is in allocated space.
+ * The group file will be locked and opened for writing. The
+ * new entry will be output, etc.
+ */
+
+output:
+ if (setuid(0)) {
+ fprintf(stderr, _("Cannot change ID to root.\n"));
+ SYSLOG((LOG_ERR, "can't setuid(0)"));
+ closelog();
+ exit(1);
+ }
+ pwd_init();
+
+ if (! gr_lock ()) {
+ fprintf(stderr, _("%s: can't get lock\n"), Prog);
+ SYSLOG((LOG_WARN, "failed to get lock for /etc/group\n"));
+ exit (1);
+ }
+#ifdef SHADOWGRP
+ if (is_shadowgrp && ! sgr_lock ()) {
+ fprintf(stderr, _("%s: can't get shadow lock\n"), Prog);
+ SYSLOG((LOG_WARN, "failed to get lock for /etc/gshadow\n"));
+ exit (1);
+ }
+#endif
+ if (! gr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: can't open file\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot open /etc/group\n"));
+ exit (1);
+ }
+#ifdef SHADOWGRP
+ if (is_shadowgrp && ! sgr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow file\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot open /etc/gshadow\n"));
+ exit (1);
+ }
+#endif
+ if (! gr_update (&grent)) {
+ fprintf(stderr, _("%s: can't update entry\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot update /etc/group\n"));
+ exit (1);
+ }
+#ifdef SHADOWGRP
+ if (is_shadowgrp && ! sgr_update (&sgent)) {
+ fprintf(stderr, _("%s: can't update shadow entry\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot update /etc/gshadow\n"));
+ exit (1);
+ }
+#endif
+ if (! gr_close ()) {
+ fprintf(stderr, _("%s: can't re-write file\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot re-write /etc/group\n"));
+ exit (1);
+ }
+#ifdef SHADOWGRP
+ if (is_shadowgrp && ! sgr_close ()) {
+ fprintf(stderr, _("%s: can't re-write shadow file\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot re-write /etc/gshadow\n"));
+ exit (1);
+ }
+ if (is_shadowgrp)
+ sgr_unlock ();
+#endif
+ if (! gr_unlock ()) {
+ fprintf(stderr, _("%s: can't unlock file\n"), Prog);
+ exit (1);
+ }
+#ifdef NDBM
+ if (gr_dbm_present() && ! gr_dbm_update (&grent)) {
+ fprintf(stderr, _("%s: can't update DBM files\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot update /etc/group DBM files\n"));
+ exit (1);
+ }
+ endgrent ();
+#ifdef SHADOWGRP
+ if (is_shadowgrp && sg_dbm_present() && ! sg_dbm_update (&sgent)) {
+ fprintf(stderr, _("%s: can't update DBM shadow files\n"), Prog);
+ SYSLOG((LOG_WARN, "cannot update /etc/gshadow DBM files\n"));
+ exit (1);
+ }
+ endsgent ();
+#endif
+#endif
+ exit (0);
+ /*NOTREACHED*/
+}
diff --git a/current/src/groupadd.c b/current/src/groupadd.c
new file mode 100644
index 00000000..cdf92334
--- /dev/null
+++ b/current/src/groupadd.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright 1991 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: groupadd.c,v 1.16 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <grp.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include "defines.h"
+#include "prototypes.h"
+#include "chkname.h"
+
+#include "getdef.h"
+
+#include "groupio.h"
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+
+static int is_shadow_grp;
+#endif
+
+/*
+ * exit status values
+ */
+
+#define E_SUCCESS 0 /* success */
+#define E_USAGE 2 /* invalid command syntax */
+#define E_BAD_ARG 3 /* invalid argument to option */
+#define E_GID_IN_USE 4 /* gid not unique (when -o not used) */
+#define E_NAME_IN_USE 9 /* group name nut unique */
+#define E_GRP_UPDATE 10 /* can't update group file */
+
+static char *group_name;
+static gid_t group_id;
+static char *empty_list = NULL;
+
+static char *Prog;
+
+static int oflg = 0; /* permit non-unique group ID to be specified with -g */
+static int gflg = 0; /* ID value for the new group */
+static int fflg = 0; /* if group already exists, do nothing and exit(0) */
+
+#ifdef NDBM
+extern int gr_dbm_mode;
+extern int sg_dbm_mode;
+#endif
+
+extern int optind;
+extern char *optarg;
+
+/* local function prototypes */
+static void usage(void);
+static void new_grent(struct group *);
+#ifdef SHADOWGRP
+static void new_sgent(struct sgrp *);
+#endif
+static void grp_update(void);
+static void find_new_gid(void);
+static void check_new_name(void);
+static void process_flags(int, char **);
+static void close_files(void);
+static void open_files(void);
+static void fail_exit(int);
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: groupadd [-g gid [-o]] group\n"));
+ exit(E_USAGE);
+}
+
+/*
+ * new_grent - initialize the values in a group file entry
+ *
+ * new_grent() takes all of the values that have been entered and
+ * fills in a (struct group) with them.
+ */
+
+static void
+new_grent(struct group *grent)
+{
+ memzero(grent, sizeof *grent);
+ grent->gr_name = group_name;
+ grent->gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
+ grent->gr_gid = group_id;
+ grent->gr_mem = &empty_list;
+}
+
+#ifdef SHADOWGRP
+/*
+ * new_sgent - initialize the values in a shadow group file entry
+ *
+ * new_sgent() takes all of the values that have been entered and
+ * fills in a (struct sgrp) with them.
+ */
+
+static void
+new_sgent(struct sgrp *sgent)
+{
+ memzero(sgent, sizeof *sgent);
+ sgent->sg_name = group_name;
+ sgent->sg_passwd = "!"; /* XXX warning: const */
+ sgent->sg_adm = &empty_list;
+ sgent->sg_mem = &empty_list;
+}
+#endif /* SHADOWGRP */
+
+/*
+ * grp_update - add new group file entries
+ *
+ * grp_update() writes the new records to the group files.
+ */
+
+static void
+grp_update(void)
+{
+ struct group grp;
+#ifdef SHADOWGRP
+ struct sgrp sgrp;
+#endif /* SHADOWGRP */
+
+ /*
+ * Create the initial entries for this new group.
+ */
+
+ new_grent (&grp);
+#ifdef SHADOWGRP
+ new_sgent (&sgrp);
+#endif /* SHADOWGRP */
+
+ /*
+ * Write out the new group file entry.
+ */
+
+ if (! gr_update (&grp)) {
+ fprintf(stderr, _("%s: error adding new group entry\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef NDBM
+
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+ if (gr_dbm_present() && ! gr_dbm_update (&grp)) {
+ fprintf(stderr, _("%s: cannot add new dbm group entry\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ endgrent ();
+#endif /* NDBM */
+
+#ifdef SHADOWGRP
+
+ /*
+ * Write out the new shadow group entries as well.
+ */
+
+ if (is_shadow_grp && ! sgr_update (&sgrp)) {
+ fprintf(stderr, _("%s: error adding new group entry\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef NDBM
+
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+ if (is_shadow_grp && sg_dbm_present() && ! sg_dbm_update (&sgrp)) {
+ fprintf(stderr, _("%s: cannot add new dbm group entry\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ endsgent ();
+#endif /* NDBM */
+#endif /* SHADOWGRP */
+ SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n",
+ group_name, group_id));
+}
+
+/*
+ * find_new_gid - find the next available GID
+ *
+ * find_new_gid() locates the next highest unused GID in the group
+ * file, or checks the given group ID against the existing ones for
+ * uniqueness.
+ */
+
+static void
+find_new_gid(void)
+{
+ const struct group *grp;
+ gid_t gid_min, gid_max;
+
+ gid_min = getdef_num("GID_MIN", 100);
+ gid_max = getdef_num("GID_MAX", 60000);
+
+ /*
+ * Start with some GID value if the user didn't provide us with
+ * one already.
+ */
+
+ if (! gflg)
+ group_id = gid_min;
+
+ /*
+ * Search the entire group file, either looking for this
+ * GID (if the user specified one with -g) or looking for the
+ * largest unused value.
+ */
+
+#ifdef NO_GETGRENT
+ gr_rewind();
+ while ((grp = gr_next())) {
+#else
+ setgrent();
+ while ((grp = getgrent())) {
+#endif
+ if (strcmp(group_name, grp->gr_name) == 0) {
+ if (fflg) {
+ fail_exit(E_SUCCESS);
+ }
+ fprintf(stderr, _("%s: name %s is not unique\n"),
+ Prog, group_name);
+ fail_exit(E_NAME_IN_USE);
+ }
+ if (gflg && group_id == grp->gr_gid) {
+ if (fflg) {
+ /* turn off -g and search again */
+ gflg = 0;
+#ifdef NO_GETGRENT
+ gr_rewind();
+#else
+ setgrent();
+#endif
+ continue;
+ }
+ fprintf(stderr, _("%s: gid %ld is not unique\n"),
+ Prog, (long) group_id);
+ fail_exit(E_GID_IN_USE);
+ }
+ if (! gflg && grp->gr_gid >= group_id) {
+ if (grp->gr_gid > gid_max)
+ continue;
+ group_id = grp->gr_gid + 1;
+ }
+ }
+ if (!gflg && group_id == gid_max + 1) {
+ for (group_id = gid_min; group_id < gid_max; group_id++) {
+#ifdef NO_GETGRENT
+ gr_rewind();
+ while ((grp = gr_next()) && grp->gr_gid != group_id)
+ ;
+ if (!grp)
+ break;
+#else
+ if (!getgrgid(group_id))
+ break;
+#endif
+ }
+ if (group_id == gid_max) {
+ fprintf(stderr, _("%s: can't get unique gid\n"),
+ Prog);
+ fail_exit(E_GID_IN_USE);
+ }
+ }
+}
+
+/*
+ * check_new_name - check the new name for validity
+ *
+ * check_new_name() insures that the new name doesn't contain
+ * any illegal characters.
+ */
+
+static void
+check_new_name(void)
+{
+ if (check_group_name(group_name))
+ return;
+
+ /*
+ * All invalid group names land here.
+ */
+
+ fprintf(stderr, _("%s: %s is a not a valid group name\n"),
+ Prog, group_name);
+
+ exit(E_BAD_ARG);
+}
+
+/*
+ * process_flags - perform command line argument setting
+ *
+ * process_flags() interprets the command line arguments and sets
+ * the values that the user will be created with accordingly. The
+ * values are checked for sanity.
+ */
+
+static void
+process_flags(int argc, char **argv)
+{
+ char *cp;
+ int arg;
+
+ while ((arg = getopt(argc, argv, "og:O:f")) != EOF) {
+ switch (arg) {
+ case 'g':
+ gflg++;
+ if (! isdigit (optarg[0]))
+ usage ();
+
+ group_id = strtol(optarg, &cp, 10);
+ if (*cp != '\0') {
+ fprintf(stderr, _("%s: invalid group %s\n"),
+ Prog, optarg);
+ fail_exit(E_BAD_ARG);
+ }
+ break;
+ case 'o':
+ oflg++;
+ break;
+ case 'O':
+ /*
+ * override login.defs defaults (-O name=value)
+ * example: -O GID_MIN=100 -O GID_MAX=499
+ * note: -O GID_MIN=10,GID_MAX=499 doesn't work yet
+ */
+ cp = strchr(optarg, '=');
+ if (!cp) {
+ fprintf(stderr,
+ _("%s: -O requires NAME=VALUE\n"),
+ Prog);
+ exit(E_BAD_ARG);
+ }
+ /* terminate name, point to value */
+ *cp++ = '\0';
+ if (putdef_str(optarg, cp) < 0)
+ exit(E_BAD_ARG);
+ break;
+ case 'f':
+ /*
+ * "force" - do nothing, just exit(0), if the
+ * specified group already exists. With -g, if
+ * specified gid already exists, choose another
+ * (unique) gid (turn off -g). Based on the
+ * RedHat's patch from shadow-utils-970616-9.
+ */
+ fflg++;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (oflg && !gflg)
+ usage();
+
+ if (optind != argc - 1)
+ usage();
+
+ group_name = argv[argc - 1];
+ check_new_name();
+}
+
+/*
+ * close_files - close all of the files that were opened
+ *
+ * close_files() closes all of the files that were opened for this
+ * new group. This causes any modified entries to be written out.
+ */
+
+static void
+close_files(void)
+{
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite group file\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ gr_unlock();
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif /* SHADOWGRP */
+}
+
+/*
+ * open_files - lock and open the group files
+ *
+ * open_files() opens the two group files.
+ */
+
+static void
+open_files(void)
+{
+ if (! gr_lock ()) {
+ fprintf(stderr, _("%s: unable to lock group file\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (! gr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open group file\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow_grp && ! sgr_lock ()) {
+ fprintf(stderr, _("%s: unable to lock shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp && ! sgr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#endif /* SHADOWGRP */
+}
+
+/*
+ * fail_exit - exit with an error code after unlocking files
+ */
+
+static void
+fail_exit(int code)
+{
+ (void) gr_unlock ();
+#ifdef SHADOWGRP
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif
+ exit (code);
+}
+
+/*
+ * main - groupadd command
+ */
+
+int
+main(int argc, char **argv)
+{
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+#ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present();
+#endif
+
+ /*
+ * The open routines for the DBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
+
+#ifdef NDBM
+ gr_dbm_mode = O_RDWR;
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif /* SHADOWGRP */
+#endif /* NDBM */
+ process_flags(argc, argv);
+
+ /*
+ * Start with a quick check to see if the group exists.
+ */
+
+ if (getgrnam(group_name)) {
+ if (fflg) {
+ exit(E_SUCCESS);
+ }
+ fprintf(stderr, _("%s: group %s exists\n"), Prog, group_name);
+ exit(E_NAME_IN_USE);
+ }
+
+ /*
+ * Do the hard stuff - open the files, create the group entries,
+ * then close and update the files.
+ */
+
+ open_files();
+
+ if (!gflg || !oflg)
+ find_new_gid();
+
+ grp_update();
+
+ close_files();
+ exit(E_SUCCESS);
+ /*NOTREACHED*/
+}
diff --git a/current/src/groupdel.c b/current/src/groupdel.c
new file mode 100644
index 00000000..7ddc3922
--- /dev/null
+++ b/current/src/groupdel.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: groupdel.c,v 1.12 2000/09/02 18:40:43 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <grp.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+#include "prototypes.h"
+#include "defines.h"
+
+static char *group_name;
+static char *Prog;
+static int errors;
+
+#ifdef NDBM
+extern int gr_dbm_mode;
+extern int sg_dbm_mode;
+#endif
+
+#include "groupio.h"
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+
+static int is_shadow_grp;
+#endif
+
+/*
+ * exit status values
+ */
+
+#define E_SUCCESS 0 /* success */
+#define E_USAGE 2 /* invalid command syntax */
+#define E_NOTFOUND 6 /* specified group doesn't exist */
+#define E_GROUP_BUSY 8 /* can't remove user's primary group */
+#define E_GRP_UPDATE 10 /* can't update group file */
+
+/* local function prototypes */
+static void usage(void);
+static void grp_update(void);
+static void close_files(void);
+static void open_files(void);
+static void group_busy(gid_t);
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: groupdel group\n"));
+ exit(E_USAGE);
+}
+
+/*
+ * grp_update - update group file entries
+ *
+ * grp_update() writes the new records to the group files.
+ */
+
+static void
+grp_update(void)
+{
+#ifdef NDBM
+ struct group *ogrp;
+#endif
+
+ if (!gr_remove(group_name)) {
+ fprintf(stderr, _("%s: error removing group entry\n"), Prog);
+ errors++;
+ }
+#ifdef NDBM
+
+ /*
+ * Update the DBM group file
+ */
+
+ if (gr_dbm_present()) {
+ if ((ogrp = getgrnam (group_name)) &&
+ ! gr_dbm_remove (ogrp)) {
+ fprintf(stderr, _("%s: error removing group dbm entry\n"),
+ Prog);
+ errors++;
+ }
+ }
+ endgrent ();
+#endif /* NDBM */
+
+#ifdef SHADOWGRP
+
+ /*
+ * Delete the shadow group entries as well.
+ */
+
+ if (is_shadow_grp && ! sgr_remove (group_name)) {
+ fprintf(stderr, _("%s: error removing shadow group entry\n"),
+ Prog);
+ errors++;
+ }
+#ifdef NDBM
+
+ /*
+ * Update the DBM shadow group file
+ */
+
+ if (is_shadow_grp && sg_dbm_present()) {
+ if (! sg_dbm_remove (group_name)) {
+ fprintf(stderr,
+ _("%s: error removing shadow group dbm entry\n"),
+ Prog);
+ errors++;
+ }
+ }
+ endsgent ();
+#endif /* NDBM */
+#endif /* SHADOWGRP */
+ SYSLOG((LOG_INFO, "remove group `%s'\n", group_name));
+ return;
+}
+
+/*
+ * close_files - close all of the files that were opened
+ *
+ * close_files() closes all of the files that were opened for this
+ * new group. This causes any modified entries to be written out.
+ */
+
+static void
+close_files(void)
+{
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite group file\n"), Prog);
+ errors++;
+ }
+ gr_unlock();
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite shadow group file\n"),
+ Prog);
+ errors++;
+ }
+ if (is_shadow_grp)
+ sgr_unlock();
+#endif /* SHADOWGRP */
+}
+
+/*
+ * open_files - lock and open the group files
+ *
+ * open_files() opens the two group files.
+ */
+
+static void
+open_files(void)
+{
+ if (!gr_lock()) {
+ fprintf(stderr, _("%s: unable to lock group file\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (!gr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open group file\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_lock()) {
+ fprintf(stderr, _("%s: unable to lock shadow group file\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp && !sgr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open shadow group file\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+#endif /* SHADOWGRP */
+}
+
+/*
+ * group_busy - check if this is any user's primary group
+ *
+ * group_busy verifies that this group is not the primary group
+ * for any user. You must remove all users before you remove
+ * the group.
+ */
+
+static void
+group_busy(gid_t gid)
+{
+ struct passwd *pwd;
+
+ /*
+ * Nice slow linear search.
+ */
+
+ setpwent ();
+
+ while ((pwd = getpwent ()) && pwd->pw_gid != gid)
+ ;
+
+ endpwent ();
+
+ /*
+ * If pwd isn't NULL, it stopped becaues the gid's matched.
+ */
+
+ if (pwd == (struct passwd *) 0)
+ return;
+
+ /*
+ * Can't remove the group.
+ */
+
+ fprintf(stderr, _("%s: cannot remove user's primary group.\n"), Prog);
+ exit(E_GROUP_BUSY);
+}
+
+/*
+ * main - groupdel command
+ *
+ * The syntax of the groupdel command is
+ *
+ * groupdel group
+ *
+ * The named group will be deleted.
+ */
+
+int
+main(int argc, char **argv)
+{
+ struct group *grp;
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc != 2)
+ usage ();
+
+ group_name = argv[1];
+
+ OPENLOG(Prog);
+
+#ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present();
+#endif
+
+ /*
+ * The open routines for the DBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
+
+#ifdef NDBM
+ gr_dbm_mode = O_RDWR;
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif /* SHADOWGRP */
+#endif /* NDBM */
+
+ /*
+ * Start with a quick check to see if the group exists.
+ */
+
+ if (! (grp = getgrnam(group_name))) {
+ fprintf(stderr, _("%s: group %s does not exist\n"),
+ Prog, group_name);
+ exit(E_NOTFOUND);
+ }
+#ifdef USE_NIS
+
+ /*
+ * Make sure this isn't a NIS group
+ */
+
+ if (__isgrNIS ()) {
+ char *nis_domain;
+ char *nis_master;
+
+ fprintf(stderr, _("%s: group %s is a NIS group\n"),
+ Prog, group_name);
+
+ if (! yp_get_default_domain (&nis_domain) &&
+ ! yp_master (nis_domain, "group.byname",
+ &nis_master)) {
+ fprintf (stderr, _("%s: %s is the NIS master\n"),
+ Prog, nis_master);
+ }
+ exit(E_NOTFOUND);
+ }
+#endif
+
+ /*
+ * Now check to insure that this isn't the primary group of
+ * anyone.
+ */
+
+ group_busy (grp->gr_gid);
+
+ /*
+ * Do the hard stuff - open the files, delete the group entries,
+ * then close and update the files.
+ */
+
+ open_files ();
+
+ grp_update ();
+
+ close_files ();
+ exit(errors == 0 ? E_SUCCESS : E_GRP_UPDATE);
+ /*NOTREACHED*/
+}
diff --git a/current/src/groupmod.c b/current/src/groupmod.c
new file mode 100644
index 00000000..6fc9bbd9
--- /dev/null
+++ b/current/src/groupmod.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: groupmod.c,v 1.14 2000/09/02 18:40:44 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <grp.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include "prototypes.h"
+#include "chkname.h"
+#include "defines.h"
+
+#include "groupio.h"
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+
+static int is_shadow_grp;
+#endif
+
+/*
+ * exit status values
+ */
+
+#define E_SUCCESS 0 /* success */
+#define E_USAGE 2 /* invalid command syntax */
+#define E_BAD_ARG 3 /* invalid argument to option */
+#define E_GID_IN_USE 4 /* gid already in use (and no -o) */
+#define E_NOTFOUND 6 /* specified group doesn't exist */
+#define E_NAME_IN_USE 9 /* group name already in use */
+#define E_GRP_UPDATE 10 /* can't update group file */
+
+static char *group_name;
+static char *group_newname;
+static gid_t group_id;
+static gid_t group_newid;
+
+static char *Prog;
+
+static int
+ oflg = 0, /* permit non-unique group ID to be specified with -g */
+ gflg = 0, /* new ID value for the group */
+ nflg = 0; /* a new name has been specified for the group */
+
+#ifdef NDBM
+extern int gr_dbm_mode;
+extern int sg_dbm_mode;
+#endif
+
+extern int optind;
+extern char *optarg;
+
+/* local function prototypes */
+static void usage(void);
+static void new_grent(struct group *);
+#ifdef SHADOWGRP
+static void new_sgent(struct sgrp *);
+#endif
+static void grp_update(void);
+static void check_new_gid(void);
+static void check_new_name(void);
+static void process_flags(int, char **);
+static void close_files(void);
+static void open_files(void);
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: groupmod [-g gid [-o]] [-n name] group\n"));
+ exit(E_USAGE);
+}
+
+/*
+ * new_grent - updates the values in a group file entry
+ *
+ * new_grent() takes all of the values that have been entered and
+ * fills in a (struct group) with them.
+ */
+
+static void
+new_grent(struct group *grent)
+{
+ if (nflg)
+ grent->gr_name = xstrdup (group_newname);
+
+ if (gflg)
+ grent->gr_gid = group_newid;
+}
+
+#ifdef SHADOWGRP
+/*
+ * new_sgent - updates the values in a shadow group file entry
+ *
+ * new_sgent() takes all of the values that have been entered and
+ * fills in a (struct sgrp) with them.
+ */
+
+static void
+new_sgent(struct sgrp *sgent)
+{
+ if (nflg)
+ sgent->sg_name = xstrdup (group_newname);
+}
+#endif /* SHADOWGRP */
+
+/*
+ * grp_update - update group file entries
+ *
+ * grp_update() writes the new records to the group files.
+ */
+
+static void
+grp_update(void)
+{
+ struct group grp;
+ const struct group *ogrp;
+#ifdef SHADOWGRP
+ struct sgrp sgrp;
+ const struct sgrp *osgrp = NULL;
+#endif /* SHADOWGRP */
+
+ /*
+ * Get the current settings for this group.
+ */
+
+ ogrp = gr_locate(group_name);
+ if (!ogrp) {
+ fprintf(stderr,
+ _("%s: %s not found in /etc/group\n"),
+ Prog, group_name);
+ exit(E_GRP_UPDATE);
+ }
+ grp = *ogrp;
+ new_grent (&grp);
+#ifdef SHADOWGRP
+ if (is_shadow_grp && (osgrp = sgr_locate(group_name))) {
+ sgrp = *osgrp;
+ new_sgent (&sgrp);
+ }
+#endif /* SHADOWGRP */
+
+ /*
+ * Write out the new group file entry.
+ */
+
+ if (!gr_update(&grp)) {
+ fprintf(stderr, _("%s: error adding new group entry\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (nflg && !gr_remove(group_name)) {
+ fprintf(stderr, _("%s: error removing group entry\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+#ifdef NDBM
+
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+ if (gr_dbm_present()) {
+ if (!gr_dbm_update(&grp)) {
+ fprintf(stderr,
+ _("%s: cannot add new dbm group entry\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (nflg && (ogrp = getgrnam(group_name)) &&
+ !gr_dbm_remove(ogrp)) {
+ fprintf(stderr,
+ _("%s: error removing group dbm entry\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ endgrent ();
+ }
+#endif /* NDBM */
+
+#ifdef SHADOWGRP
+
+ /*
+ * Make sure there was a shadow entry to begin with. Skip
+ * down to "out" if there wasn't. Can't just return because
+ * there might be some syslogging to do.
+ */
+
+ if (! osgrp)
+ goto out;
+
+ /*
+ * Write out the new shadow group entries as well.
+ */
+
+ if (!sgr_update(&sgrp)) {
+ fprintf(stderr, _("%s: error adding new group entry\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (nflg && !sgr_remove(group_name)) {
+ fprintf(stderr, _("%s: error removing group entry\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+#ifdef NDBM
+
+ /*
+ * Update the DBM shadow group file with the new entry as well.
+ */
+
+ if (sg_dbm_present()) {
+ if (!sg_dbm_update(&sgrp)) {
+ fprintf(stderr,
+ _("%s: cannot add new dbm shadow group entry\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (nflg && ! sg_dbm_remove (group_name)) {
+ fprintf (stderr,
+ _("%s: error removing shadow group dbm entry\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ endsgent ();
+ }
+#endif /* NDBM */
+out:
+#endif /* SHADOWGRP */
+
+ if (nflg)
+ SYSLOG((LOG_INFO, "change group `%s' to `%s'\n",
+ group_name, group_newname));
+
+ if (gflg)
+ SYSLOG((LOG_INFO, "change gid for `%s' to %d\n",
+ nflg ? group_newname:group_name, group_newid));
+}
+
+/*
+ * check_new_gid - check the new GID value for uniqueness
+ *
+ * check_new_gid() insures that the new GID value is unique.
+ */
+
+static void
+check_new_gid(void)
+{
+ /*
+ * First, the easy stuff. If the ID can be duplicated, or if
+ * the ID didn't really change, just return. If the ID didn't
+ * change, turn off those flags. No sense doing needless work.
+ */
+
+ if (group_id == group_newid) {
+ gflg = 0;
+ return;
+ }
+
+ if (oflg || ! getgrgid (group_newid))
+ return;
+
+ /*
+ * Tell the user what they did wrong.
+ */
+
+ fprintf(stderr,
+ _("%s: %ld is not a unique gid\n"),
+ Prog, (long) group_newid);
+ exit(E_GID_IN_USE);
+}
+
+/*
+ * check_new_name - check the new name for uniqueness
+ *
+ * check_new_name() insures that the new name does not exist
+ * already. You can't have the same name twice, period.
+ */
+
+static void
+check_new_name(void)
+{
+ /*
+ * Make sure they are actually changing the name.
+ */
+
+ if (strcmp(group_name, group_newname) == 0) {
+ nflg = 0;
+ return;
+ }
+
+ if (check_group_name(group_newname)) {
+
+ /*
+ * If the entry is found, too bad.
+ */
+
+ if (getgrnam(group_newname)) {
+ fprintf(stderr, _("%s: %s is not a unique name\n"),
+ Prog, group_newname);
+ exit(E_NAME_IN_USE);
+ }
+ return;
+ }
+
+ /*
+ * All invalid group names land here.
+ */
+
+ fprintf(stderr, _("%s: %s is a not a valid group name\n"),
+ Prog, group_newname);
+ exit(E_BAD_ARG);
+}
+
+/*
+ * process_flags - perform command line argument setting
+ *
+ * process_flags() interprets the command line arguments and sets
+ * the values that the user will be created with accordingly. The
+ * values are checked for sanity.
+ */
+
+static void
+process_flags(int argc, char **argv)
+{
+ char *end;
+ int arg;
+
+ while ((arg = getopt (argc, argv, "og:n:")) != EOF) {
+ switch (arg) {
+ case 'g':
+ gflg++;
+ group_newid = strtol(optarg, &end, 10);
+ if (*end != '\0') {
+ fprintf(stderr,
+ _("%s: invalid group %s\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ break;
+ case 'n':
+ nflg++;
+ group_newname = optarg;
+ break;
+ case 'o':
+ oflg++;
+ break;
+ default:
+ usage ();
+ }
+ }
+ if (oflg && !gflg)
+ usage();
+
+ if (optind != argc - 1)
+ usage();
+
+ group_name = argv[argc - 1];
+}
+
+/*
+ * close_files - close all of the files that were opened
+ *
+ * close_files() closes all of the files that were opened for this
+ * new group. This causes any modified entries to be written out.
+ */
+
+static void
+close_files(void)
+{
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite group file\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+ gr_unlock();
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite shadow group file\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif /* SHADOWGRP */
+}
+
+/*
+ * open_files - lock and open the group files
+ *
+ * open_files() opens the two group files.
+ */
+
+static void
+open_files(void)
+{
+ if (!gr_lock()) {
+ fprintf(stderr, _("%s: unable to lock group file\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (!gr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open group file\n"), Prog);
+ exit(E_GRP_UPDATE);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_lock()) {
+ fprintf(stderr, _("%s: unable to lock shadow group file\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp && !sgr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open shadow group file\n"),
+ Prog);
+ exit(E_GRP_UPDATE);
+ }
+#endif /* SHADOWGRP */
+}
+
+/*
+ * main - groupmod command
+ *
+ * The syntax of the groupmod command is
+ *
+ * groupmod [ -g gid [ -o ]] [ -n name ] group
+ *
+ * The flags are
+ * -g - specify a new group ID value
+ * -o - permit the group ID value to be non-unique
+ * -n - specify a new group name
+ */
+
+int
+main(int argc, char **argv)
+{
+ struct group *grp;
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+#ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present();
+#endif
+
+ /*
+ * The open routines for the DBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
+
+#ifdef NDBM
+ gr_dbm_mode = O_RDWR;
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif /* SHADOWGRP */
+#endif /* NDBM */
+ process_flags (argc, argv);
+
+ /*
+ * Start with a quick check to see if the group exists.
+ */
+
+ if (!(grp = getgrnam(group_name))) {
+ fprintf(stderr, _("%s: group %s does not exist\n"),
+ Prog, group_name);
+ exit(E_NOTFOUND);
+ } else
+ group_id = grp->gr_gid;
+
+#ifdef USE_NIS
+
+ /*
+ * Now make sure it isn't an NIS group.
+ */
+
+ if (__isgrNIS ()) {
+ char *nis_domain;
+ char *nis_master;
+
+ fprintf(stderr, _("%s: group %s is a NIS group\n"),
+ Prog, group_name);
+
+ if (! yp_get_default_domain (&nis_domain) &&
+ ! yp_master (nis_domain, "group.byname",
+ &nis_master)) {
+ fprintf(stderr, _("%s: %s is the NIS master\n"),
+ Prog, nis_master);
+ }
+ exit(E_NOTFOUND);
+ }
+#endif
+
+ if (gflg)
+ check_new_gid ();
+
+ if (nflg)
+ check_new_name ();
+
+ /*
+ * Do the hard stuff - open the files, create the group entries,
+ * then close and update the files.
+ */
+
+ open_files ();
+
+ grp_update ();
+
+ close_files ();
+ exit(E_SUCCESS);
+ /*NOTREACHED*/
+}
diff --git a/current/src/groups.c b/current/src/groups.c
new file mode 100644
index 00000000..875272c8
--- /dev/null
+++ b/current/src/groups.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 1991 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: groups.c,v 1.6 2000/08/26 18:27:18 marekm Exp $")
+
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include "prototypes.h"
+#include "defines.h"
+
+/* local function prototypes */
+static void print_groups(const char *);
+
+/*
+ * print_groups - print the groups which the named user is a member of
+ *
+ * print_groups() scans the groups file for the list of groups
+ * which the user is listed as being a member of.
+ */
+
+static void
+print_groups(const char *member)
+{
+ int groups = 0;
+ struct group *grp;
+ struct passwd *pwd;
+ int flag = 0;
+
+ setgrent ();
+
+ if ((pwd = getpwnam(member)) == 0) {
+ fprintf(stderr, _("unknown user %s\n"), member);
+ exit(1);
+ }
+ while ((grp = getgrent ())) {
+ if (is_on_list(grp->gr_mem, member)) {
+ if (groups++)
+ putchar (' ');
+
+ printf ("%s", grp->gr_name);
+ if (grp->gr_gid == pwd->pw_gid)
+ flag = 1;
+ }
+ }
+ if (! flag && (grp = getgrgid (pwd->pw_gid))) {
+ if (groups++)
+ putchar (' ');
+
+ printf ("%s", grp->gr_name);
+ }
+ if (groups)
+ putchar ('\n');
+}
+
+/*
+ * groups - print out the groups a process is a member of
+ */
+
+int
+main(int argc, char **argv)
+{
+#ifdef HAVE_GETGROUPS
+ int ngroups;
+ GETGROUPS_T groups[NGROUPS_MAX];
+ int pri_grp;
+ int i;
+ struct group *gr;
+#else
+ char *logname;
+ char *getlogin();
+#endif
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc == 1) {
+
+ /*
+ * Called with no arguments - give the group set
+ * for the current user.
+ */
+
+#ifdef HAVE_GETGROUPS
+ /*
+ * This system supports concurrent group sets, so
+ * I can ask the system to tell me which groups are
+ * currently set for this process.
+ */
+
+ ngroups = getgroups(NGROUPS_MAX, groups);
+ if (ngroups < 0) {
+ perror("getgroups");
+ exit(1);
+ }
+
+ /*
+ * The groupset includes the primary group as well.
+ */
+
+ pri_grp = getegid ();
+ for (i = 0;i < ngroups;i++)
+ if (pri_grp == (int) groups[i])
+ break;
+
+ if (i != ngroups)
+ pri_grp = -1;
+
+ /*
+ * Print out the name of every group in the current
+ * group set. Unknown groups are printed as their
+ * decimal group ID values.
+ */
+
+ if (pri_grp != -1) {
+ if ((gr = getgrgid (pri_grp)))
+ printf ("%s", gr->gr_name);
+ else
+ printf ("%d", pri_grp);
+ }
+
+ for (i = 0;i < ngroups;i++) {
+ if (i || pri_grp != -1)
+ putchar (' ');
+
+ if ((gr = getgrgid (groups[i])))
+ printf ("%s", gr->gr_name);
+ else
+ printf ("%ld", (long) groups[i]);
+ }
+ putchar ('\n');
+#else
+ /*
+ * This system does not have the getgroups() system
+ * call, so I must check the groups file directly.
+ */
+
+ if ((logname = getlogin ()))
+ print_groups (logname);
+ else
+ exit (1);
+#endif
+ } else {
+
+ /*
+ * The invoker wanted to know about some other
+ * user. Use that name to look up the groups instead.
+ */
+
+ print_groups (argv[1]);
+ }
+ exit (0);
+}
diff --git a/current/src/grpck.c b/current/src/grpck.c
new file mode 100644
index 00000000..50fc2eab
--- /dev/null
+++ b/current/src/grpck.c
@@ -0,0 +1,649 @@
+/*
+ * Copyright 1992 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: grpck.c,v 1.14 2000/09/02 18:40:44 marekm Exp $")
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <grp.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include "chkname.h"
+#include <pwd.h>
+
+#include "commonio.h"
+
+#include "groupio.h"
+extern void __gr_del_entry(const struct commonio_entry *);
+extern struct commonio_entry *__gr_get_head(void);
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+extern void __sgr_del_entry(const struct commonio_entry *);
+extern struct commonio_entry *__sgr_get_head(void);
+#endif
+
+/*
+ * Exit codes
+ */
+
+#define E_OKAY 0
+#define E_USAGE 1
+#define E_BAD_ENTRY 2
+#define E_CANT_OPEN 3
+#define E_CANT_LOCK 4
+#define E_CANT_UPDATE 5
+
+/*
+ * Global variables
+ */
+
+extern int optind;
+extern char *optarg;
+
+/*
+ * Local variables
+ */
+
+static char *Prog;
+static const char *grp_file = GROUP_FILE;
+#ifdef SHADOWGRP
+static const char *sgr_file = SGROUP_FILE;
+#endif
+static int read_only = 0;
+
+/* local function prototypes */
+static void usage(void);
+static int yes_or_no(void);
+static void delete_member(char **, const char *);
+
+/*
+ * usage - print syntax message and exit
+ */
+
+static void
+usage(void)
+{
+#ifdef SHADOWGRP
+ fprintf(stderr, _("Usage: %s [ -r ] [ group [ gshadow ] ]\n"), Prog);
+#else
+ fprintf(stderr, _("Usage: %s [ -r ] [ group ]\n"), Prog);
+#endif
+ exit(E_USAGE);
+}
+
+/*
+ * yes_or_no - get answer to question from the user
+ */
+
+static int
+yes_or_no(void)
+{
+ char buf[80];
+
+ /*
+ * In read-only mode all questions are answered "no".
+ */
+
+ if (read_only) {
+ puts(_("No"));
+ return 0;
+ }
+
+ /*
+ * Get a line and see what the first character is.
+ */
+
+ if (fgets(buf, sizeof buf, stdin))
+ return buf[0] == 'y' || buf[0] == 'Y';
+
+ return 0;
+}
+
+/*
+ * delete_member - delete an entry in a list of members
+ */
+
+static void
+delete_member(char **list, const char *member)
+{
+ int i;
+
+ for (i = 0; list[i]; i++)
+ if (list[i] == member)
+ break;
+
+ if (list[i])
+ for (; list[i]; i++)
+ list[i] = list[i + 1];
+}
+
+/*
+ * grpck - verify group file integrity
+ */
+
+int
+main(int argc, char **argv)
+{
+ int arg;
+ int errors = 0;
+ int deleted = 0;
+ int i;
+ struct commonio_entry *gre, *tgre;
+ struct group *grp;
+#ifdef SHADOWGRP
+ struct commonio_entry *sge, *tsge;
+ struct sgrp *sgr;
+ int is_shadow = 0;
+#endif
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+ /*
+ * Parse the command line arguments
+ */
+
+ while ((arg = getopt(argc, argv, "qr")) != EOF) {
+ switch (arg) {
+ case 'q':
+ /* quiet - ignored for now */
+ break;
+ case 'r':
+ read_only = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ /*
+ * Make certain we have the right number of arguments
+ */
+
+#ifdef SHADOWGRP
+ if (optind != argc && optind + 1 != argc && optind + 2 != argc)
+#else
+ if (optind != argc && optind + 1 != argc)
+#endif
+ usage();
+
+ /*
+ * If there are two left over filenames, use those as the
+ * group and group password filenames.
+ */
+
+ if (optind != argc) {
+ grp_file = argv[optind];
+ gr_name(grp_file);
+ }
+#ifdef SHADOWGRP
+ if (optind + 2 == argc) {
+ sgr_file = argv[optind + 1];
+ sgr_name(sgr_file);
+ is_shadow = 1;
+ } else if (optind == argc)
+ is_shadow = sgr_file_present();
+#endif
+
+ /*
+ * Lock the files if we aren't in "read-only" mode
+ */
+
+ if (!read_only) {
+ if (!gr_lock()) {
+ fprintf(stderr, _("%s: cannot lock file %s\n"), Prog, grp_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN,"cannot lock %s\n",grp_file));
+ closelog();
+ exit(E_CANT_LOCK);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow && !sgr_lock()) {
+ fprintf(stderr, _("%s: cannot lock file %s\n"), Prog, sgr_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN,"cannot lock %s\n",sgr_file));
+ closelog();
+ exit(E_CANT_LOCK);
+ }
+#endif
+ }
+
+ /*
+ * Open the files. Use O_RDONLY if we are in read_only mode,
+ * O_RDWR otherwise.
+ */
+
+ if (!gr_open(read_only ? O_RDONLY : O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open file %s\n"), Prog, grp_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN, "cannot open %s\n", grp_file));
+ closelog();
+ exit(E_CANT_OPEN);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow && !sgr_open(read_only ? O_RDONLY : O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open file %s\n"), Prog, sgr_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN, "cannot open %s\n", sgr_file));
+ closelog();
+ exit(E_CANT_OPEN);
+ }
+#endif
+
+ /*
+ * Loop through the entire group file.
+ */
+
+ for (gre = __gr_get_head(); gre; gre = gre->next) {
+ /*
+ * Skip all NIS entries.
+ */
+
+ if (gre->line[0] == '+' || gre->line[0] == '-')
+ continue;
+
+ /*
+ * Start with the entries that are completely corrupt.
+ * They have no (struct group) entry because they couldn't
+ * be parsed properly.
+ */
+
+ if (!gre->eptr) {
+
+ /*
+ * Tell the user this entire line is bogus and
+ * ask them to delete it.
+ */
+
+ printf(_("invalid group file entry\n"));
+ printf(_("delete line `%s'? "), gre->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (!yes_or_no())
+ continue;
+
+ /*
+ * All group file deletions wind up here. This
+ * code removes the current entry from the linked
+ * list. When done, it skips back to the top of
+ * the loop to try out the next list element.
+ */
+
+delete_gr:
+ SYSLOG((LOG_INFO, "delete group line `%s'\n",
+ gre->line));
+ deleted++;
+
+ __gr_del_entry(gre);
+ continue;
+ }
+
+ /*
+ * Group structure is good, start using it.
+ */
+
+ grp = gre->eptr;
+
+ /*
+ * Make sure this entry has a unique name.
+ */
+
+ for (tgre = __gr_get_head(); tgre; tgre = tgre->next) {
+
+ const struct group *ent = tgre->eptr;
+
+ /*
+ * Don't check this entry
+ */
+
+ if (tgre == gre)
+ continue;
+
+ /*
+ * Don't check invalid entries.
+ */
+
+ if (!ent)
+ continue;
+
+ if (strcmp(grp->gr_name, ent->gr_name) != 0)
+ continue;
+
+ /*
+ * Tell the user this entry is a duplicate of
+ * another and ask them to delete it.
+ */
+
+ puts(_("duplicate group entry\n"));
+ printf(_("delete line `%s'? "), gre->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (yes_or_no())
+ goto delete_gr;
+ }
+
+ /*
+ * Check for invalid group names. --marekm
+ */
+ if (!check_group_name(grp->gr_name)) {
+ errors++;
+ printf(_("invalid group name `%s'\n"), grp->gr_name);
+ }
+
+ /*
+ * Check for a Slackware bug. Make sure GID is not -1
+ * (it has special meaning for some syscalls). --marekm
+ */
+
+ if (grp->gr_gid == (gid_t) -1) {
+ errors++;
+ printf(_("group %s: bad GID (%d)\n"),
+ grp->gr_name, (int) grp->gr_gid);
+ }
+
+ /*
+ * Workaround for a NYS libc 5.3.12 bug on RedHat 4.2 -
+ * groups with no members are returned as groups with
+ * one member "", causing grpck to fail. --marekm
+ */
+
+ if (grp->gr_mem[0] && !grp->gr_mem[1] && *(grp->gr_mem[0]) == '\0')
+ grp->gr_mem[0] = (char *) 0;
+
+ /*
+ * Make sure each member exists
+ */
+
+ for (i = 0; grp->gr_mem[i]; i++) {
+ if (getpwnam(grp->gr_mem[i]))
+ continue;
+ /*
+ * Can't find this user. Remove them
+ * from the list.
+ */
+
+ errors++;
+ printf(_("group %s: no user %s\n"),
+ grp->gr_name, grp->gr_mem[i]);
+ printf(_("delete member `%s'? "), grp->gr_mem[i]);
+
+ if (!yes_or_no())
+ continue;
+
+ SYSLOG((LOG_INFO, "delete member `%s' group `%s'\n",
+ grp->gr_mem[i], grp->gr_name));
+ deleted++;
+ delete_member(grp->gr_mem, grp->gr_mem[i]);
+ gre->changed = 1;
+ __gr_set_changed();
+ }
+ }
+
+#ifdef SHADOWGRP
+ if (!is_shadow)
+ goto shadow_done;
+
+ /*
+ * Loop through the entire shadow group file.
+ */
+
+ for (sge = __sgr_get_head(); sge; sge = sge->next) {
+
+ /*
+ * Start with the entries that are completely corrupt.
+ * They have no (struct sgrp) entry because they couldn't
+ * be parsed properly.
+ */
+
+ if (!sge->eptr) {
+
+ /*
+ * Tell the user this entire line is bogus and
+ * ask them to delete it.
+ */
+
+ printf(_("invalid shadow group file entry\n"));
+ printf(_("delete line `%s'? "), sge->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (!yes_or_no())
+ continue;
+
+ /*
+ * All shadow group file deletions wind up here.
+ * This code removes the current entry from the
+ * linked list. When done, it skips back to the
+ * top of the loop to try out the next list element.
+ */
+
+delete_sg:
+ SYSLOG((LOG_INFO, "delete shadow line `%s'\n",
+ sge->line));
+ deleted++;
+
+ __sgr_del_entry(sge);
+ continue;
+ }
+
+ /*
+ * Shadow group structure is good, start using it.
+ */
+
+ sgr = sge->eptr;
+
+ /*
+ * Make sure this entry has a unique name.
+ */
+
+ for (tsge = __sgr_get_head(); tsge; tsge = tsge->next) {
+
+ const struct sgrp *ent = tsge->eptr;
+
+ /*
+ * Don't check this entry
+ */
+
+ if (tsge == sge)
+ continue;
+
+ /*
+ * Don't check invalid entries.
+ */
+
+ if (!ent)
+ continue;
+
+ if (strcmp(sgr->sg_name, ent->sg_name) != 0)
+ continue;
+
+ /*
+ * Tell the user this entry is a duplicate of
+ * another and ask them to delete it.
+ */
+
+ puts(_("duplicate shadow group entry\n"));
+ printf(_("delete line `%s'? "), sge->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (yes_or_no())
+ goto delete_sg;
+ }
+
+ /*
+ * Make sure this entry exists in the /etc/group file.
+ */
+
+ if (!gr_locate(sgr->sg_name)) {
+ puts(_("no matching group file entry\n"));
+ printf(_("delete line `%s'? "), sge->line);
+ errors++;
+ if (yes_or_no())
+ goto delete_sg;
+ }
+
+ /*
+ * Make sure each administrator exists
+ */
+
+ for (i = 0; sgr->sg_adm[i]; i++) {
+ if (getpwnam(sgr->sg_adm[i]))
+ continue;
+ /*
+ * Can't find this user. Remove them
+ * from the list.
+ */
+
+ errors++;
+ printf(_("shadow group %s: no administrative user %s\n"),
+ sgr->sg_name, sgr->sg_adm[i]);
+ printf(_("delete administrative member `%s'? "), sgr->sg_adm[i]);
+
+ if (!yes_or_no())
+ continue;
+
+ SYSLOG((LOG_INFO,
+ "delete admin `%s' from shadow group `%s'\n",
+ sgr->sg_adm[i], sgr->sg_name));
+ deleted++;
+ delete_member(sgr->sg_adm, sgr->sg_adm[i]);
+ sge->changed = 1;
+ __sgr_set_changed();
+ }
+
+ /*
+ * Make sure each member exists
+ */
+
+ for (i = 0; sgr->sg_mem[i]; i++) {
+ if (getpwnam(sgr->sg_mem[i]))
+ continue;
+
+ /*
+ * Can't find this user. Remove them
+ * from the list.
+ */
+
+ errors++;
+ printf(_("shadow group %s: no user %s\n"),
+ sgr->sg_name, sgr->sg_mem[i]);
+ printf(_("delete member `%s'? "), sgr->sg_mem[i]);
+
+ if (!yes_or_no())
+ continue;
+
+ SYSLOG((LOG_INFO,
+ "delete member `%s' from shadow group `%s'\n",
+ sgr->sg_mem[i], sgr->sg_name));
+ deleted++;
+ delete_member(sgr->sg_mem, sgr->sg_mem[i]);
+ sge->changed = 1;
+ __sgr_set_changed();
+ }
+ }
+
+shadow_done:
+#endif /* SHADOWGRP */
+
+ /*
+ * All done. If there were no deletions we can just abandon any
+ * changes to the files.
+ */
+
+ if (deleted) {
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: cannot update file %s\n"),
+ Prog, grp_file);
+ exit(E_CANT_UPDATE);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow && !sgr_close()) {
+ fprintf(stderr, _("%s: cannot update file %s\n"),
+ Prog, sgr_file);
+ exit(E_CANT_UPDATE);
+ }
+#endif
+ }
+
+ /*
+ * Don't be anti-social - unlock the files when you're done.
+ */
+
+#ifdef SHADOWGRP
+ if (is_shadow)
+ sgr_unlock();
+#endif
+ (void) gr_unlock();
+
+ /*
+ * Tell the user what we did and exit.
+ */
+
+ if (errors)
+#ifdef NDBM
+ printf(deleted ?
+ _("%s: the files have been updated; run mkpasswd\n") :
+ _("%s: no changes\n"), Prog);
+#else
+ printf(deleted ?
+ _("%s: the files have been updated\n") :
+ _("%s: no changes\n"), Prog);
+#endif
+
+ exit(errors ? E_BAD_ENTRY : E_OKAY);
+}
diff --git a/current/src/grpconv.c b/current/src/grpconv.c
new file mode 100644
index 00000000..8e641fd3
--- /dev/null
+++ b/current/src/grpconv.c
@@ -0,0 +1,173 @@
+/*
+ * grpconv - create or update /etc/gshadow with information from
+ * /etc/group.
+ *
+ * Copyright (C) 1996, Marek Michalkiewicz
+ * <marekm@i17linuxb.ists.pwr.wroc.pl>
+ * This program may be freely used and distributed. If you improve
+ * it, please send me your changes. Thanks!
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <grp.h>
+#include "prototypes.h"
+
+#ifdef SHADOWGRP
+
+#include "groupio.h"
+#include "sgroupio.h"
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: grpconv.c,v 1.11 2000/08/26 18:27:18 marekm Exp $")
+
+static int group_locked = 0;
+static int gshadow_locked = 0;
+
+/* local function prototypes */
+static void fail_exit(int);
+
+static void
+fail_exit(int status)
+{
+ if (group_locked)
+ gr_unlock();
+ if (gshadow_locked)
+ sgr_unlock();
+ exit(status);
+}
+
+int
+main(int argc, char **argv)
+{
+ const struct group *gr;
+ struct group grent;
+ const struct sgrp *sg;
+ struct sgrp sgent;
+ char *Prog = argv[0];
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (!gr_lock()) {
+ fprintf(stderr, _("%s: can't lock group file\n"), Prog);
+ fail_exit(5);
+ }
+ group_locked++;
+ if (!gr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open group file\n"), Prog);
+ fail_exit(1);
+ }
+
+ if (!sgr_lock()) {
+ fprintf(stderr, _("%s: can't lock shadow group file\n"), Prog);
+ fail_exit(5);
+ }
+ gshadow_locked++;
+ if (!sgr_open(O_CREAT | O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow group file\n"), Prog);
+ fail_exit(1);
+ }
+
+ /*
+ * Remove /etc/gshadow entries for groups not in /etc/group.
+ */
+ sgr_rewind();
+ while ((sg = sgr_next())) {
+ if (gr_locate(sg->sg_name))
+ continue;
+
+ if (!sgr_remove(sg->sg_name)) {
+ /*
+ * This shouldn't happen (the entry exists) but...
+ */
+ fprintf(stderr, _("%s: can't remove shadow group %s\n"),
+ Prog, sg->sg_name);
+ fail_exit(3);
+ }
+ }
+
+ /*
+ * Update shadow group passwords if non-shadow password is not "x".
+ * Add any missing shadow group entries.
+ */
+ gr_rewind();
+ while ((gr = gr_next())) {
+ sg = sgr_locate(gr->gr_name);
+ if (sg) {
+#if 0 /* because of sg_mem, but see below */
+ if (strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) == 0)
+ continue;
+#endif
+ /* update existing shadow group entry */
+ sgent = *sg;
+ if (strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) != 0)
+ sgent.sg_passwd = gr->gr_passwd;
+ } else {
+ static char *empty = 0;
+
+ /* add new shadow group entry */
+ memset(&sgent, 0, sizeof sgent);
+ sgent.sg_name = gr->gr_name;
+ sgent.sg_passwd = gr->gr_passwd;
+ sgent.sg_adm = &empty;
+ }
+ /*
+ * XXX - sg_mem is redundant, it is currently always a copy
+ * of gr_mem. Very few programs actually use sg_mem, and
+ * all of them are in the shadow suite... Maybe this field
+ * could be used for something else? Any suggestions?
+ */
+ sgent.sg_mem = gr->gr_mem;
+
+ if (!sgr_update(&sgent)) {
+ fprintf(stderr,
+ _("%s: can't update shadow entry for %s\n"),
+ Prog, sgent.sg_name);
+ fail_exit(3);
+ }
+ /* remove password from /etc/group */
+ grent = *gr;
+ grent.gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
+ if (!gr_update(&grent)) {
+ fprintf(stderr,
+ _("%s: can't update entry for group %s\n"),
+ Prog, grent.gr_name);
+ fail_exit(3);
+ }
+ }
+
+ if (!sgr_close()) {
+ fprintf(stderr, _("%s: can't update shadow group file\n"), Prog);
+ fail_exit(3);
+ }
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: can't update group file\n"), Prog);
+ fail_exit(3);
+ }
+ sgr_unlock();
+ gr_unlock();
+ return 0;
+}
+#else /* !SHADOWGRP */
+int
+main(int argc, char **argv)
+{
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ fprintf(stderr, _("%s: not configured for shadow group support.\n"),
+ argv[0]);
+ exit(1);
+}
+#endif /* !SHADOWGRP */
diff --git a/current/src/grpunconv.c b/current/src/grpunconv.c
new file mode 100644
index 00000000..59cb4994
--- /dev/null
+++ b/current/src/grpunconv.c
@@ -0,0 +1,131 @@
+/*
+ * grpunconv - update /etc/group with information from /etc/gshadow.
+ *
+ * Copyright (C) 1996, Michael Meskes <meskes@debian.org>
+ * using sources from Marek Michalkiewicz
+ * <marekm@i17linuxb.ists.pwr.wroc.pl>
+ * This program may be freely used and distributed. If you improve
+ * it, please send me your changes. Thanks!
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: grpunconv.c,v 1.10 2000/08/26 18:27:18 marekm Exp $")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <grp.h>
+#include "prototypes.h"
+
+#ifdef SHADOWGRP
+
+#include "groupio.h"
+#include "sgroupio.h"
+
+static int group_locked = 0;
+static int gshadow_locked = 0;
+
+/* local function prototypes */
+static void fail_exit(int);
+
+static void
+fail_exit(int status)
+{
+ if (group_locked)
+ gr_unlock();
+ if (gshadow_locked)
+ sgr_unlock();
+ exit(status);
+}
+
+int
+main(int argc, char **argv)
+{
+ const struct group *gr;
+ struct group grent;
+ const struct sgrp *sg;
+ char *Prog = argv[0];
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (!sgr_file_present())
+ exit(0); /* no /etc/gshadow, nothing to do */
+
+ if (!gr_lock()) {
+ fprintf(stderr, _("%s: can't lock group file\n"), Prog);
+ fail_exit(5);
+ }
+ group_locked++;
+ if (!gr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open group file\n"), Prog);
+ fail_exit(1);
+ }
+
+ if (!sgr_lock()) {
+ fprintf(stderr, _("%s: can't lock shadow group file\n"), Prog);
+ fail_exit(5);
+ }
+ gshadow_locked++;
+ if (!sgr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow group file\n"), Prog);
+ fail_exit(1);
+ }
+
+ /*
+ * Update group passwords if non-shadow password is "x".
+ */
+ gr_rewind();
+ while ((gr = gr_next())) {
+ sg = sgr_locate(gr->gr_name);
+ if (sg && strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) == 0) {
+ /* add password to /etc/group */
+ grent = *gr;
+ grent.gr_passwd = sg->sg_passwd;
+ if (!gr_update(&grent)) {
+ fprintf(stderr,
+ _("%s: can't update entry for group %s\n"),
+ Prog, grent.gr_name);
+ fail_exit(3);
+ }
+ }
+ }
+
+ if (!sgr_close()) {
+ fprintf(stderr, _("%s: can't update shadow group file\n"), Prog);
+ fail_exit(3);
+ }
+
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: can't update group file\n"), Prog);
+ fail_exit(3);
+ }
+
+ if (unlink(SGROUP_FILE) != 0) {
+ fprintf(stderr, _("%s: can't delete shadow group file\n"), Prog);
+ fail_exit(3);
+ }
+
+ sgr_unlock();
+ gr_unlock();
+ return 0;
+}
+#else /* !SHADOWGRP */
+int
+main(int argc, char **argv)
+{
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ fprintf(stderr, _("%s: not configured for shadow group support.\n"), argv[0]);
+ exit(1);
+}
+#endif /* !SHADOWGRP */
diff --git a/current/src/id.c b/current/src/id.c
new file mode 100644
index 00000000..28839a02
--- /dev/null
+++ b/current/src/id.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * id - print current process user identification information
+ *
+ * Print the current process identifiers. This includes the
+ * UID, GID, effective-UID and effective-GID. Optionally print
+ * the concurrent group set if the current system supports it.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: id.c,v 1.6 2000/08/26 18:27:18 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include "defines.h"
+
+/* local function prototypes */
+static void usage(void);
+
+static void
+usage(void)
+{
+#ifdef HAVE_GETGROUPS
+ fprintf(stderr, _("usage: id [ -a ]\n"));
+#else
+ fprintf(stderr, _("usage: id\n"));
+#endif
+ exit(1);
+}
+
+/*ARGSUSED*/
+int
+main(int argc, char **argv)
+{
+ uid_t ruid, euid;
+ gid_t rgid, egid;
+ int i;
+/*
+ * This block of declarations is particularly strained because of several
+ * different ways of doing concurrent groups. Old BSD systems used int
+ * for gid's, but short for the type passed to getgroups(). Newer systems
+ * use gid_t for everything. Some systems have a small and fixed NGROUPS,
+ * usually about 16 or 32. Others use bigger values.
+ */
+#ifdef HAVE_GETGROUPS
+ GETGROUPS_T groups[NGROUPS_MAX];
+ int ngroups;
+ int aflg = 0;
+#endif
+ struct passwd *pw;
+ struct group *gr;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+#ifdef HAVE_GETGROUPS
+ /*
+ * See if the -a flag has been given to print out the
+ * concurrent group set.
+ */
+
+ if (argc > 1) {
+ if (argc > 2 || strcmp (argv[1], "-a"))
+ usage();
+ else
+ aflg = 1;
+ }
+#else
+ if (argc > 1)
+ usage();
+#endif
+
+ ruid = getuid();
+ euid = geteuid();
+ rgid = getgid();
+ egid = getegid();
+
+ /*
+ * Print out the real user ID and group ID. If the user or
+ * group does not exist, just give the numerical value.
+ */
+
+ pw = getpwuid(ruid);
+ if (pw)
+ printf(_("uid=%d(%s)"), (int) ruid, pw->pw_name);
+ else
+ printf(_("uid=%d"), (int) ruid);
+
+ gr = getgrgid(rgid);
+ if (gr)
+ printf(_(" gid=%d(%s)"), (int) rgid, gr->gr_name);
+ else
+ printf(_(" gid=%d"), (int) rgid);
+
+ /*
+ * Print out the effective user ID and group ID if they are
+ * different from the real values.
+ */
+
+ if (ruid != euid) {
+ pw = getpwuid(euid);
+ if (pw)
+ printf(_(" euid=%d(%s)"), (int) euid, pw->pw_name);
+ else
+ printf(_(" euid=%d"), (int) euid);
+ }
+ if (rgid != egid) {
+ gr = getgrgid(egid);
+ if (gr)
+ printf(_(" egid=%d(%s)"), (int) egid, gr->gr_name);
+ else
+ printf(_(" egid=%d"), (int) egid);
+ }
+
+#ifdef HAVE_GETGROUPS
+ /*
+ * Print out the concurrent group set if the user has requested
+ * it. The group numbers will be printed followed by their
+ * names.
+ */
+
+ if (aflg && (ngroups = getgroups (NGROUPS_MAX, groups)) != -1) {
+
+ /*
+ * Start off the group message. It will be of the format
+ *
+ * groups=###(aaa),###(aaa),###(aaa)
+ *
+ * where "###" is a numerical value and "aaa" is the
+ * corresponding name for each respective numerical value.
+ */
+
+ printf(_(" groups="));
+ for (i = 0; i < ngroups; i++) {
+ if (i)
+ putchar(',');
+
+ gr = getgrgid(groups[i]);
+ if (gr)
+ printf("%d(%s)", (int) groups[i], gr->gr_name);
+ else
+ printf("%d", (int) groups[i]);
+ }
+ }
+#endif
+
+ /*
+ * Finish off the line.
+ */
+
+ putchar('\n');
+ exit(0);
+ /*NOTREACHED*/
+}
diff --git a/current/src/lastlog.c b/current/src/lastlog.c
new file mode 100644
index 00000000..a7957ac7
--- /dev/null
+++ b/current/src/lastlog.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: lastlog.c,v 1.6 2000/08/26 18:27:18 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <time.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#if HAVE_LASTLOG_H
+#include <lastlog.h>
+#else
+#include "lastlog_.h"
+#endif
+
+/*
+ * Needed for MkLinux DR1/2/2.1 - J.
+ */
+#ifndef LASTLOG_FILE
+#define LASTLOG_FILE "/var/log/lastlog"
+#endif
+
+static FILE *lastlogfile; /* lastlog file stream */
+static off_t user; /* one single user, specified on command line */
+static int days; /* number of days to consider for print command */
+static time_t seconds; /* that number of days in seconds */
+
+static int uflg = 0; /* set if user is a valid user id */
+static int tflg = 0; /* print is restricted to most recent days */
+static struct lastlog lastlog; /* scratch structure to play with ... */
+static struct stat statbuf; /* fstat buffer for file size */
+static struct passwd *pwent;
+
+extern char *optarg;
+
+#define NOW (time ((time_t *) 0))
+
+/* local function prototypes */
+static void print(void);
+static void print_one(const struct passwd *);
+
+int
+main(int argc, char **argv)
+{
+ int c;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if ((lastlogfile = fopen (LASTLOG_FILE,"r")) == (FILE *) 0) {
+ perror (LASTLOG_FILE);
+ exit (1);
+ }
+ while ((c = getopt (argc, argv, "u:t:")) != EOF) {
+ switch (c) {
+ case 'u':
+ pwent = getpwnam (optarg);
+ if (!pwent) {
+ fprintf(stderr,
+ _("Unknown User: %s\n"),
+ optarg);
+ exit (1);
+ }
+ uflg++;
+ user = pwent->pw_uid;
+ break;
+ case 't':
+ days = atoi (optarg);
+ seconds = days * DAY;
+ tflg++;
+ break;
+ }
+ }
+ print ();
+ fclose (lastlogfile);
+ exit (0);
+ /*NOTREACHED*/
+}
+
+static void
+print(void)
+{
+ off_t offset;
+
+ if (uflg) {
+ offset = (unsigned long) user * sizeof lastlog;
+ if (fstat (fileno (lastlogfile), &statbuf)) {
+ perror(LASTLOG_FILE);
+ return;
+ }
+ if (offset >= statbuf.st_size)
+ return;
+
+ fseek (lastlogfile, offset, SEEK_SET);
+ if (fread ((char *) &lastlog, sizeof lastlog, 1,
+ lastlogfile) == 1)
+ print_one (pwent);
+ else
+ perror (LASTLOG_FILE);
+ } else {
+ setpwent ();
+ while ((pwent = getpwent ())) {
+ user = pwent->pw_uid;
+ offset = (unsigned long) user * sizeof lastlog;
+ fseek (lastlogfile, offset, SEEK_SET);
+ if (fread ((char *) &lastlog, sizeof lastlog, 1,
+ lastlogfile) != 1)
+ continue;
+
+ if (tflg && NOW - lastlog.ll_time > seconds)
+ continue;
+
+ print_one (pwent);
+ }
+ }
+}
+
+static void
+print_one(const struct passwd *pw)
+{
+ static int once;
+ char *cp;
+ struct tm *tm;
+#ifdef HAVE_STRFTIME
+ char ptime[80];
+#endif
+
+ if (! pw)
+ return;
+
+ if (! once) {
+#ifdef HAVE_LL_HOST
+ printf(_("Username Port From Latest\n"));
+#else
+ printf(_("Username Port Latest\n"));
+#endif
+ once++;
+ }
+ tm = localtime (&lastlog.ll_time);
+#ifdef HAVE_STRFTIME
+ strftime(ptime, sizeof(ptime), "%a %b %e %H:%M:%S %z %Y", tm);
+ cp = ptime;
+#else
+ cp = asctime (tm);
+ cp[24] = '\0';
+#endif
+
+ if(lastlog.ll_time == (time_t) 0)
+ cp = _("**Never logged in**\0");
+
+#ifdef HAVE_LL_HOST
+ printf ("%-16s %-8.8s %-16.16s %s\n", pw->pw_name,
+ lastlog.ll_line, lastlog.ll_host, cp);
+#else
+ printf ("%-16s\t%-8.8s %s\n", pw->pw_name,
+ lastlog.ll_line, cp);
+#endif
+}
diff --git a/current/src/login.c b/current/src/login.c
new file mode 100644
index 00000000..fa5b9170
--- /dev/null
+++ b/current/src/login.c
@@ -0,0 +1,1314 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: login.c,v 1.18 2000/09/02 18:40:44 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#if HAVE_UTMPX_H
+#include <utmpx.h>
+#else
+#include <utmp.h>
+#endif
+#include <signal.h>
+
+#if HAVE_LASTLOG_H
+#include <lastlog.h>
+#else
+#include "lastlog_.h"
+#endif
+
+#include "faillog.h"
+#include "failure.h"
+#include "pwauth.h"
+#include "getdef.h"
+#include "dialchk.h"
+
+#ifdef SVR4_SI86_EUA
+#include <sys/proc.h>
+#include <sys/sysi86.h>
+#endif
+
+#ifdef RADIUS
+/*
+ * Support for RADIUS authentication based on a hacked util-linux login
+ * source sent to me by Jon Lewis. Not tested. You need to link login
+ * with the radauth.c file (not included here - it doesn't have a clear
+ * copyright statement, and I don't want to have problems with Debian
+ * putting the whole package in non-free because of this). --marekm
+ */
+#include "radlogin.h"
+#endif
+
+#ifdef UT_ADDR
+#include <netdb.h>
+#endif
+
+#ifdef USE_PAM
+#include "pam_defs.h"
+
+static const struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+static pam_handle_t *pamh = NULL;
+
+#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
+ fprintf(stderr,"\n%s\n",PAM_STRERROR(pamh, retcode)); \
+ syslog(LOG_ERR,"%s",PAM_STRERROR(pamh, retcode)); \
+ pam_end(pamh, retcode); exit(1); \
+ }
+#define PAM_END { retcode = pam_close_session(pamh,0); \
+ pam_end(pamh,retcode); }
+
+#endif /* USE_PAM */
+
+/*
+ * Needed for MkLinux DR1/2/2.1 - J.
+ */
+#ifndef LASTLOG_FILE
+#define LASTLOG_FILE "/var/log/lastlog"
+#endif
+
+const char *hostname = "";
+
+struct passwd pwent;
+#if HAVE_UTMPX_H
+struct utmpx utxent, failent;
+struct utmp utent;
+#else
+struct utmp utent, failent;
+#endif
+struct lastlog lastlog;
+static int pflg = 0;
+static int fflg = 0;
+#ifdef RLOGIN
+static int rflg = 0;
+#else
+#define rflg 0
+#endif
+static int hflg = 0;
+static int preauth_flag = 0;
+
+/*
+ * Global variables.
+ */
+
+static char *Prog;
+static int amroot;
+static int timeout;
+
+/*
+ * External identifiers.
+ */
+
+extern char **newenvp;
+extern size_t newenvc;
+
+extern void dolastlog(struct lastlog *, const struct passwd *, const char *, const char *);
+
+extern int optind;
+extern char *optarg;
+extern char **environ;
+
+extern int login_access(const char *, const char *);
+extern void login_fbtab(const char *, uid_t, gid_t);
+
+#ifndef ALARM
+#define ALARM 60
+#endif
+
+#ifndef RETRIES
+#define RETRIES 3
+#endif
+
+static struct faillog faillog;
+
+#define NO_SHADOW "no shadow password for `%s'%s\n"
+#define BAD_PASSWD "invalid password for `%s'%s\n"
+#define BAD_DIALUP "invalid dialup password for `%s' on `%s'\n"
+#define BAD_TIME "invalid login time for `%s'%s\n"
+#define BAD_ROOT_LOGIN "ILLEGAL ROOT LOGIN%s\n"
+#define ROOT_LOGIN "ROOT LOGIN%s\n"
+#define FAILURE_CNT "exceeded failure limit for `%s'%s\n"
+#define REG_LOGIN "`%s' logged in%s\n"
+#define LOGIN_REFUSED "LOGIN `%s' REFUSED%s\n"
+#define REENABLED2 \
+ "login `%s' re-enabled after temporary lockout (%d failures).\n"
+#define MANY_FAILS "REPEATED login failures%s\n"
+
+/* local function prototypes */
+static void usage(void);
+static void setup_tty(void);
+static void bad_time_notify(void);
+static void check_flags(int, char * const *);
+#ifndef USE_PAM
+static void check_nologin(void);
+#endif
+static void init_env(void);
+static RETSIGTYPE alarm_handler(int);
+
+/*
+ * usage - print login command usage and exit
+ *
+ * login [ name ]
+ * login -r hostname (for rlogind)
+ * login -h hostname (for telnetd, etc.)
+ * login -f name (for pre-authenticated login: datakit, xterm, etc.)
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: %s [-p] [name]\n"), Prog);
+ if (!amroot)
+ exit(1);
+ fprintf(stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
+#ifdef RLOGIN
+ fprintf(stderr, _(" %s [-p] -r host\n"), Prog);
+#endif
+ exit(1);
+}
+
+
+static void
+setup_tty(void)
+{
+ TERMIO termio;
+
+ GTTY(0, &termio); /* get terminal characteristics */
+
+ /*
+ * Add your favorite terminal modes here ...
+ */
+
+ termio.c_lflag |= ISIG|ICANON|ECHO|ECHOE;
+ termio.c_iflag |= ICRNL;
+
+#if defined(ECHOKE) && defined(ECHOCTL)
+ termio.c_lflag |= ECHOKE|ECHOCTL;
+#endif
+#if defined(ECHOPRT) && defined(NOFLSH) && defined(TOSTOP)
+ termio.c_lflag &= ~(ECHOPRT|NOFLSH|TOSTOP);
+#endif
+#ifdef ONLCR
+ termio.c_oflag |= ONLCR;
+#endif
+
+#ifdef SUN4
+
+ /*
+ * Terminal setup for SunOS 4.1 courtesy of Steve Allen
+ * at UCO/Lick.
+ */
+
+ termio.c_cc[VEOF] = '\04';
+ termio.c_cflag &= ~CSIZE;
+ termio.c_cflag |= (PARENB|CS7);
+ termio.c_lflag |= (ISIG|ICANON|ECHO|IEXTEN);
+ termio.c_iflag |= (BRKINT|IGNPAR|ISTRIP|IMAXBEL|ICRNL|IXON);
+ termio.c_iflag &= ~IXANY;
+ termio.c_oflag |= (XTABS|OPOST|ONLCR);
+#endif
+#if 0
+ termio.c_cc[VERASE] = getdef_num("ERASECHAR", '\b');
+ termio.c_cc[VKILL] = getdef_num("KILLCHAR", '\025');
+#else
+ /* leave these values unchanged if not specified in login.defs */
+ termio.c_cc[VERASE] = getdef_num("ERASECHAR", termio.c_cc[VERASE]);
+ termio.c_cc[VKILL] = getdef_num("KILLCHAR", termio.c_cc[VKILL]);
+#endif
+
+ /*
+ * ttymon invocation prefers this, but these settings won't come into
+ * effect after the first username login
+ */
+
+ STTY(0, &termio);
+}
+
+
+/*
+ * Tell the user that this is not the right time to login at this tty
+ */
+static void
+bad_time_notify(void)
+{
+#ifdef HUP_MESG_FILE
+ FILE *mfp;
+
+ if ((mfp = fopen(HUP_MESG_FILE, "r")) != NULL) {
+ int c;
+
+ while ((c = fgetc(mfp)) != EOF) {
+ if (c == '\n')
+ putchar('\r');
+ putchar(c);
+ }
+ fclose(mfp);
+ } else
+#endif
+ printf(_("Invalid login time\n"));
+ fflush(stdout);
+}
+
+
+static void
+check_flags(int argc, char * const *argv)
+{
+ int arg;
+
+ /*
+ * Check the flags for proper form. Every argument starting with
+ * "-" must be exactly two characters long. This closes all the
+ * clever rlogin, telnet, and getty holes.
+ */
+ for (arg = 1; arg < argc; arg++) {
+ if (argv[arg][0] == '-' && strlen(argv[arg]) > 2)
+ usage();
+ }
+}
+
+#ifndef USE_PAM
+static void
+check_nologin(void)
+{
+ char *fname;
+
+ /*
+ * Check to see if system is turned off for non-root users.
+ * This would be useful to prevent users from logging in
+ * during system maintenance. We make sure the message comes
+ * out for root so she knows to remove the file if she's
+ * forgotten about it ...
+ */
+
+ fname = getdef_str("NOLOGINS_FILE");
+ if (fname != NULL && access(fname, F_OK) == 0) {
+ FILE *nlfp;
+ int c;
+
+ /*
+ * Cat the file if it can be opened, otherwise just
+ * print a default message
+ */
+
+ if ((nlfp = fopen (fname, "r"))) {
+ while ((c = getc (nlfp)) != EOF) {
+ if (c == '\n')
+ putchar ('\r');
+
+ putchar (c);
+ }
+ fflush (stdout);
+ fclose (nlfp);
+ } else
+ printf(_("\nSystem closed for routine maintenance\n"));
+ /*
+ * Non-root users must exit. Root gets the message, but
+ * gets to login.
+ */
+
+ if (pwent.pw_uid != 0) {
+ closelog();
+ exit(0);
+ }
+ printf(_("\n[Disconnect bypassed -- root login allowed.]\n"));
+ }
+}
+#endif /* !USE_PAM */
+
+static void
+init_env(void)
+{
+ char *cp, *tmp;
+
+ if ((tmp = getenv("LANG"))) {
+ addenv("LANG", tmp);
+ }
+
+ /*
+ * Add the timezone environmental variable so that time functions
+ * work correctly.
+ */
+
+ if ((tmp = getenv("TZ"))) {
+ addenv("TZ", tmp);
+ } else if ((cp = getdef_str("ENV_TZ")))
+ addenv(*cp == '/' ? tz(cp) : cp, NULL);
+
+ /*
+ * Add the clock frequency so that profiling commands work
+ * correctly.
+ */
+
+ if ((tmp = getenv("HZ"))) {
+ addenv("HZ", tmp);
+ } else if ((cp = getdef_str("ENV_HZ")))
+ addenv(cp, NULL);
+}
+
+
+static RETSIGTYPE
+alarm_handler(int sig)
+{
+ fprintf(stderr, _("\nLogin timed out after %d seconds.\n"), timeout);
+ exit(0);
+}
+
+
+/*
+ * login - create a new login session for a user
+ *
+ * login is typically called by getty as the second step of a
+ * new user session. getty is responsible for setting the line
+ * characteristics to a reasonable set of values and getting
+ * the name of the user to be logged in. login may also be
+ * called to create a new user session on a pty for a variety
+ * of reasons, such as X servers or network logins.
+ *
+ * the flags which login supports are
+ *
+ * -p - preserve the environment
+ * -r - perform autologin protocol for rlogin
+ * -f - do not perform authentication, user is preauthenticated
+ * -h - the name of the remote host
+ */
+
+int
+main(int argc, char **argv)
+{
+ char username[32];
+ char tty[BUFSIZ];
+#ifdef RLOGIN
+ char term[128] = "";
+#endif
+#ifdef HAVE_STRFTIME
+ char ptime[80];
+#endif
+ int reason = PW_LOGIN;
+ int delay;
+ int retries;
+ int failed;
+ int flag;
+ int subroot = 0;
+ int is_console;
+ const char *cp;
+ char *tmp;
+ char fromhost[512];
+ struct passwd *pwd;
+ char **envp = environ;
+ static char temp_pw[2];
+ static char temp_shell[] = "/bin/sh";
+#ifdef USE_PAM
+ int retcode;
+ pid_t child;
+ char *pam_user;
+#endif /* USE_PAM */
+#ifdef SHADOWPWD
+ struct spwd *spwd=NULL;
+#endif
+#ifdef RADIUS
+ RAD_USER_DATA rad_user_data;
+ int is_rad_login;
+#endif
+#if defined(RADIUS) || defined(DES_RPC) || defined(KERBEROS)
+ /* from pwauth.c */
+ extern char *clear_pass;
+ extern int wipe_clear_pass;
+
+ /*
+ * We may need the password later, don't want pw_auth() to wipe it
+ * (we do it ourselves when it is no longer needed). --marekm
+ */
+ wipe_clear_pass = 0;
+#endif
+
+ /*
+ * Some quick initialization.
+ */
+
+ sanitize_env();
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ initenv();
+
+ username[0] = '\0';
+ amroot = (getuid() == 0);
+ Prog = Basename(argv[0]);
+
+ check_flags(argc, argv);
+
+ while ((flag = getopt(argc, argv, "d:f:h:pr:")) != EOF) {
+ switch (flag) {
+ case 'p':
+ pflg++;
+ break;
+ case 'f':
+ /*
+ * username must be a separate token
+ * (-f root, *not* -froot). --marekm
+ */
+ if (optarg != argv[optind - 1])
+ usage();
+ fflg++;
+ STRFCPY(username, optarg);
+ break;
+#ifdef RLOGIN
+ case 'r':
+ rflg++;
+ hostname = optarg;
+ reason = PW_RLOGIN;
+ break;
+#endif
+ case 'h':
+ hflg++;
+ hostname = optarg;
+ reason = PW_TELNET;
+ break;
+ case 'd':
+ /* "-d device" ignored for compatibility */
+ break;
+ default:
+ usage();
+ }
+ }
+
+#ifdef RLOGIN
+ /*
+ * Neither -h nor -f should be combined with -r.
+ */
+
+ if (rflg && (hflg || fflg))
+ usage();
+#endif
+
+ /*
+ * Allow authentication bypass only if real UID is zero.
+ */
+
+ if ((rflg || fflg || hflg) && !amroot) {
+ fprintf(stderr, _("%s: permission denied\n"), Prog);
+ exit(1);
+ }
+
+ if (!isatty(0) || !isatty(1) || !isatty(2))
+ exit(1); /* must be a terminal */
+
+#if 0
+ /*
+ * Get the utmp file entry and get the tty name from it. The
+ * current process ID must match the process ID in the utmp
+ * file if there are no additional flags on the command line.
+ */
+ checkutmp(!rflg && !fflg && !hflg);
+#else
+ /*
+ * Be picky if run by normal users (possible if installed setuid
+ * root), but not if run by root. This way it still allows logins
+ * even if your getty is broken, or if something corrupts utmp,
+ * but users must "exec login" which will use the existing utmp
+ * entry (will not overwrite remote hostname). --marekm
+ */
+ checkutmp(!amroot);
+#endif
+ STRFCPY(tty, utent.ut_line);
+ is_console = console(tty);
+
+ if (rflg || hflg) {
+#ifdef UT_ADDR
+ struct hostent *he;
+
+ /*
+ * Fill in the ut_addr field (remote login IP address).
+ * XXX - login from util-linux does it, but this is not
+ * the right place to do it. The program that starts
+ * login (telnetd, rlogind) knows the IP address, so it
+ * should create the utmp entry and fill in ut_addr.
+ * gethostbyname() is not 100% reliable (the remote host
+ * may be unknown, etc.). --marekm
+ */
+ if ((he = gethostbyname(hostname))) {
+ utent.ut_addr = *((int32_t *)(he->h_addr_list[0]));
+#endif
+#ifdef UT_HOST
+ strncpy(utent.ut_host, hostname, sizeof(utent.ut_host));
+#endif
+#if HAVE_UTMPX_H
+ strncpy(utxent.ut_host, hostname, sizeof(utxent.ut_host));
+#endif
+ /*
+ * Add remote hostname to the environment. I think
+ * (not sure) I saw it once on Irix. --marekm
+ */
+ addenv("REMOTEHOST", hostname);
+ }
+#ifdef __linux__
+/* workaround for init/getty leaving junk in ut_host at least in some
+ version of RedHat. --marekm */
+ else if (amroot)
+ memzero(utent.ut_host, sizeof utent.ut_host);
+#endif
+ if (hflg && fflg) {
+ reason = PW_RLOGIN;
+ preauth_flag++;
+ }
+#ifdef RLOGIN
+ if (rflg && do_rlogin(hostname, username, sizeof username, term, sizeof term))
+ preauth_flag++;
+#endif
+
+ OPENLOG("login");
+
+ setup_tty();
+
+ umask(getdef_num("UMASK", 077));
+
+ {
+ /*
+ * Use the ULIMIT in the login.defs file, and if
+ * there isn't one, use the default value. The
+ * user may have one for themselves, but otherwise,
+ * just take what you get.
+ */
+
+ long limit = getdef_long("ULIMIT", -1L);
+
+ if (limit != -1)
+ set_filesize_limit(limit);
+ }
+
+ /*
+ * The entire environment will be preserved if the -p flag
+ * is used.
+ */
+
+ if (pflg)
+ while (*envp) /* add inherited environment, */
+ addenv(*envp++, NULL); /* some variables change later */
+
+#ifdef RLOGIN
+ if (term[0] != '\0')
+ addenv("TERM", term);
+ else
+#endif
+ /* preserve TERM from getty */
+ if (!pflg && (tmp = getenv("TERM")))
+ addenv("TERM", tmp);
+
+ init_env();
+
+ if (optind < argc) { /* get the user name */
+ if (rflg || fflg)
+ usage();
+
+#ifdef SVR4
+ /*
+ * The "-h" option can't be used with a command-line username,
+ * because telnetd invokes us as: login -h host TERM=...
+ */
+
+ if (! hflg)
+#endif
+ {
+ STRFCPY(username, argv[optind]);
+ strzero(argv[optind]);
+ ++optind;
+ }
+ }
+#ifdef SVR4
+ /*
+ * check whether ttymon has done the prompt for us already
+ */
+
+ {
+ char *ttymon_prompt;
+
+ if ((ttymon_prompt = getenv("TTYPROMPT")) != NULL &&
+ (*ttymon_prompt != 0)) {
+ /* read name, without prompt */
+ login_prompt((char *)0, username, sizeof username);
+ }
+ }
+#endif /* SVR4 */
+ if (optind < argc) /* now set command line variables */
+ set_env(argc - optind, &argv[optind]);
+
+ if (rflg || hflg)
+ cp = hostname;
+ else
+#ifdef UT_HOST
+ if (utent.ut_host[0])
+ cp = utent.ut_host;
+ else
+#endif
+#if HAVE_UTMPX_H
+ if (utxent.ut_host[0])
+ cp = utxent.ut_host;
+ else
+#endif
+ cp = "";
+
+ if (*cp)
+ snprintf(fromhost, sizeof fromhost,
+ _(" on `%.100s' from `%.200s'"), tty, cp);
+ else
+ snprintf(fromhost, sizeof fromhost, _(" on `%.100s'"), tty);
+
+top:
+ /* only allow ALARM sec. for login */
+ signal(SIGALRM, alarm_handler);
+ timeout = getdef_num("LOGIN_TIMEOUT", ALARM);
+ if (timeout > 0)
+ alarm(timeout);
+
+ environ = newenvp; /* make new environment active */
+ delay = getdef_num("FAIL_DELAY", 1);
+ retries = getdef_num("LOGIN_RETRIES", RETRIES);
+
+#ifdef USE_PAM
+ retcode = pam_start("login", username, &conv, &pamh);
+ if(retcode != PAM_SUCCESS) {
+ fprintf(stderr,"login: PAM Failure, aborting: %s\n",
+ PAM_STRERROR(pamh, retcode));
+ syslog(LOG_ERR,"Couldn't initialize PAM: %s",
+ PAM_STRERROR(pamh, retcode));
+ exit(99);
+ }
+ /* hostname & tty are either set to NULL or their correct values,
+ depending on how much we know. We also set PAM's fail delay
+ to ours. */
+ retcode = pam_set_item(pamh, PAM_RHOST, hostname);
+ PAM_FAIL_CHECK;
+ retcode = pam_set_item(pamh, PAM_TTY, tty);
+ PAM_FAIL_CHECK;
+#ifdef HAVE_PAM_FAIL_DELAY
+ retcode = pam_fail_delay(pamh, 1000000*delay);
+ PAM_FAIL_CHECK;
+#endif
+ /* if fflg == 1, then the user has already been authenticated */
+ if (!fflg || (getuid() != 0)) {
+ int failcount;
+ char hostn[256];
+ char login_prompt[256]; /* That's one hell of a prompt :) */
+
+ /* Make the login prompt look like we want it */
+ if (!gethostname(hostn, sizeof(hostn)))
+ snprintf(login_prompt, sizeof(login_prompt),
+ "%s login: ", hostn);
+ else
+ snprintf(login_prompt, sizeof(login_prompt),
+ "login: ");
+
+ retcode = pam_set_item(pamh, PAM_USER_PROMPT, login_prompt);
+ PAM_FAIL_CHECK;
+
+ /* if we didn't get a user on the command line,
+ set it to NULL */
+ pam_get_item(pamh, PAM_USER, (const void **) &pam_user);
+ if (pam_user[0] == '\0')
+ pam_set_item(pamh, PAM_USER, NULL);
+
+ /* there may be better ways to deal with some of these
+ conditions, but at least this way I don't think we'll
+ be giving away information... */
+ /* Perhaps someday we can trust that all PAM modules will
+ pay attention to failure count and get rid of
+ MAX_LOGIN_TRIES? */
+
+ retcode = pam_authenticate(pamh, 0);
+ while ((failcount++ < retries) &&
+ ((retcode == PAM_AUTH_ERR) ||
+ (retcode == PAM_USER_UNKNOWN) ||
+ (retcode == PAM_CRED_INSUFFICIENT) ||
+ (retcode == PAM_AUTHINFO_UNAVAIL))) {
+ pam_get_item(pamh, PAM_USER, (const void **) &pam_user);
+ syslog(LOG_NOTICE,"FAILED LOGIN %d FROM %s FOR %s, %s",
+ failcount, hostname, pam_user,
+ PAM_STRERROR(pamh, retcode));
+#ifdef HAVE_PAM_FAIL_DELAY
+ pam_fail_delay(pamh, 1000000*delay);
+#endif
+ fprintf(stderr, "Login incorrect\n\n");
+ pam_set_item(pamh, PAM_USER, NULL);
+ retcode = pam_authenticate(pamh, 0);
+ }
+
+ if (retcode != PAM_SUCCESS) {
+ pam_get_item(pamh, PAM_USER, (const void **) &pam_user);
+
+ if (retcode == PAM_MAXTRIES)
+ syslog(LOG_NOTICE,
+ "TOO MANY LOGIN TRIES (%d) FROM %s FOR %s, %s",
+ failcount, hostname, pam_user,
+ PAM_STRERROR(pamh, retcode));
+ else
+ syslog(LOG_NOTICE,
+ "FAILED LOGIN SESSION FROM %s FOR %s, %s",
+ hostname, pam_user,
+ PAM_STRERROR(pamh, retcode));
+
+ fprintf(stderr, "\nLogin incorrect\n");
+ pam_end(pamh, retcode);
+ exit(0);
+ }
+
+ retcode = pam_acct_mgmt(pamh, 0);
+
+ if(retcode == PAM_NEW_AUTHTOK_REQD) {
+ retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ }
+
+ PAM_FAIL_CHECK;
+ }
+
+ /* Grab the user information out of the password file for future usage
+ First get the username that we are actually using, though.
+ */
+ retcode = pam_get_item(pamh, PAM_USER, (const void **) &pam_user);
+ setpwent();
+ pwd = getpwnam(pam_user);
+
+ if (!pwd || setup_groups(pwd))
+ exit(1);
+
+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
+ PAM_FAIL_CHECK;
+
+ retcode = pam_open_session(pamh, 0);
+ PAM_FAIL_CHECK;
+
+
+#else /* ! USE_PAM */
+ while (1) { /* repeatedly get login/password pairs */
+ failed = 0; /* haven't failed authentication yet */
+#ifdef RADIUS
+ is_rad_login = 0;
+#endif
+ if (! username[0]) { /* need to get a login id */
+ if (subroot) {
+ closelog ();
+ exit (1);
+ }
+ preauth_flag = 0;
+#ifndef LOGIN_PROMPT
+#ifdef __linux__ /* hostname login: - like in util-linux login */
+ login_prompt(_("\n%s login: "), username, sizeof username);
+#else
+ login_prompt(_("login: "), username, sizeof username);
+#endif
+#else
+ login_prompt(LOGIN_PROMPT, username, sizeof username);
+#endif
+ continue;
+ }
+#endif /* ! USE_PAM */
+
+#ifdef USE_PAM
+ if (!(pwd = getpwnam(pam_user))) {
+ pwent.pw_name = pam_user;
+#else
+ if (!(pwd = getpwnam(username))) {
+ pwent.pw_name = username;
+#endif
+ strcpy(temp_pw, "!");
+ pwent.pw_passwd = temp_pw;
+ pwent.pw_shell = temp_shell;
+
+ preauth_flag = 0;
+ failed = 1;
+ } else {
+ pwent = *pwd;
+ }
+#ifndef USE_PAM
+#ifdef SHADOWPWD
+ spwd = NULL;
+ if (pwd && strcmp(pwd->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
+ spwd = getspnam(username);
+ if (spwd)
+ pwent.pw_passwd = spwd->sp_pwdp;
+ else
+ SYSLOG((LOG_WARN, NO_SHADOW, username, fromhost));
+ }
+#endif /* SHADOWPWD */
+
+ /*
+ * If the encrypted password begins with a "!", the account
+ * is locked and the user cannot login, even if they have
+ * been "pre-authenticated."
+ */
+ if (pwent.pw_passwd[0] == '!' || pwent.pw_passwd[0] == '*')
+ failed = 1;
+
+ /*
+ * The -r and -f flags provide a name which has already
+ * been authenticated by some server.
+ */
+ if (preauth_flag)
+ goto auth_ok;
+
+ /*
+ * No password prompt if logging in from listed ttys
+ * (local console). Passwords don't help much if you
+ * have physical access to the hardware anyway...
+ * Suggested by Pavel Machek <pavel@bug.ucw.cz>.
+ * NOTE: password still required for root logins!
+ */
+ if (pwd && (pwent.pw_uid != 0)
+ && is_listed("NO_PASSWORD_CONSOLE", tty, 0)) {
+ temp_pw[0] = '\0';
+ pwent.pw_passwd = temp_pw;
+ }
+
+ if (pw_auth(pwent.pw_passwd, username, reason, (char *) 0) == 0)
+ goto auth_ok;
+
+#ifdef RADIUS
+ /*
+ * If normal passwd authentication didn't work, try radius.
+ */
+
+ if (failed) {
+ pwd = rad_authenticate(&rad_user_data, username,
+ clear_pass ? clear_pass : "");
+ if (pwd) {
+ is_rad_login = 1;
+ pwent = *pwd;
+ failed = 0;
+ goto auth_ok;
+ }
+ }
+#endif /* RADIUS */
+
+ /*
+ * Don't log unknown usernames - I mistyped the password for
+ * username at least once... Should probably use LOG_AUTHPRIV
+ * for those who really want to log them. --marekm
+ */
+ SYSLOG((LOG_WARN, BAD_PASSWD,
+ (pwd || getdef_bool("LOG_UNKFAIL_ENAB")) ?
+ username : "UNKNOWN", fromhost));
+ failed = 1;
+
+auth_ok:
+ /*
+ * This is the point where all authenticated users
+ * wind up. If you reach this far, your password has
+ * been authenticated and so on.
+ */
+
+#if defined(RADIUS) && !(defined(DES_RPC) || defined(KERBEROS))
+ if (clear_pass) {
+ strzero(clear_pass);
+ clear_pass = NULL;
+ }
+#endif
+
+ if (getdef_bool("DIALUPS_CHECK_ENAB")) {
+ alarm (30);
+
+ if (! dialcheck (tty, pwent.pw_shell[0] ?
+ pwent.pw_shell:"/bin/sh")) {
+ SYSLOG((LOG_WARN, BAD_DIALUP, username, tty));
+ failed = 1;
+ }
+ }
+
+ if (! failed && pwent.pw_name && pwent.pw_uid == 0 &&
+ ! is_console) {
+ SYSLOG((LOG_CRIT, BAD_ROOT_LOGIN, fromhost));
+ failed = 1;
+ }
+#ifdef LOGIN_ACCESS
+ if (!failed && !login_access(username, *hostname ? hostname : tty)) {
+ SYSLOG((LOG_WARN, LOGIN_REFUSED, username, fromhost));
+ failed = 1;
+ }
+#endif
+ if (pwd && getdef_bool("FAILLOG_ENAB") &&
+ ! failcheck (pwent.pw_uid, &faillog, failed)) {
+ SYSLOG((LOG_CRIT, FAILURE_CNT, username, fromhost));
+ failed = 1;
+ }
+ if (! failed)
+ break;
+
+ /* don't log non-existent users */
+ if (pwd && getdef_bool("FAILLOG_ENAB"))
+ failure (pwent.pw_uid, tty, &faillog);
+ if (getdef_str("FTMP_FILE") != NULL) {
+ const char *failent_user;
+
+#if HAVE_UTMPX_H
+ failent = utxent;
+ gettimeofday(&(failent.ut_tv), NULL);
+#else
+ failent = utent;
+ time(&failent.ut_time);
+#endif
+ if (pwd) {
+ failent_user = pwent.pw_name;
+ } else {
+ if (getdef_bool("LOG_UNKFAIL_ENAB"))
+ failent_user = username;
+ else
+ failent_user = "UNKNOWN";
+ }
+ strncpy(failent.ut_user, failent_user, sizeof(failent.ut_user));
+#ifdef USER_PROCESS
+ failent.ut_type = USER_PROCESS;
+#endif
+ failtmp(&failent);
+ }
+ memzero(username, sizeof username);
+
+ if (--retries <= 0)
+ SYSLOG((LOG_CRIT, MANY_FAILS, fromhost));
+#if 1
+ /*
+ * If this was a passwordless account and we get here,
+ * login was denied (securetty, faillog, etc.). There
+ * was no password prompt, so do it now (will always
+ * fail - the bad guys won't see that the passwordless
+ * account exists at all). --marekm
+ */
+
+ if (pwent.pw_passwd[0] == '\0')
+ pw_auth("!", username, reason, (char *) 0);
+#endif
+ /*
+ * Wait a while (a la SVR4 /usr/bin/login) before attempting
+ * to login the user again. If the earlier alarm occurs
+ * before the sleep() below completes, login will exit.
+ */
+
+ if (delay > 0)
+ sleep(delay);
+
+ puts(_("Login incorrect"));
+
+ /* allow only one attempt with -r or -f */
+ if (rflg || fflg || retries <= 0) {
+ closelog();
+ exit(1);
+ }
+ } /* while (1) */
+#endif /* ! USE_PAM */
+ (void) alarm (0); /* turn off alarm clock */
+#ifndef USE_PAM /* PAM does this */
+ /*
+ * porttime checks moved here, after the user has been
+ * authenticated. now prints a message, as suggested
+ * by Ivan Nejgebauer <ian@unsux.ns.ac.yu>. --marekm
+ */
+ if (getdef_bool("PORTTIME_CHECKS_ENAB") &&
+ !isttytime(pwent.pw_name, tty, time ((time_t *) 0))) {
+ SYSLOG((LOG_WARN, BAD_TIME, username, fromhost));
+ closelog();
+ bad_time_notify();
+ exit(1);
+ }
+
+ check_nologin();
+#endif
+
+ if (getenv("IFS")) /* don't export user IFS ... */
+ addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
+
+#ifdef USE_PAM
+ setutmp(pam_user, tty, hostname); /* make entry in utmp & wtmp files */
+#else
+ setutmp(username, tty, hostname); /* make entry in utmp & wtmp files */
+#endif
+ if (pwent.pw_shell[0] == '*') { /* subsystem root */
+ subsystem (&pwent); /* figure out what to execute */
+ subroot++; /* say i was here again */
+ endpwent (); /* close all of the file which were */
+ endgrent (); /* open in the original rooted file */
+#ifdef SHADOWPWD
+ endspent (); /* system. they will be re-opened */
+#endif
+#ifdef SHADOWGRP
+ endsgent (); /* in the new rooted file system */
+#endif
+ goto top; /* go do all this all over again */
+ }
+#ifndef USE_PAM /* pam_lastlog handles this */
+ if (getdef_bool("LASTLOG_ENAB")) /* give last login and log this one */
+ dolastlog(&lastlog, &pwent, utent.ut_line, hostname);
+#endif
+
+#ifdef SVR4_SI86_EUA
+ sysi86(SI86LIMUSER, EUA_ADD_USER); /* how do we test for fail? */
+#endif
+
+#ifndef USE_PAM /* PAM handles this as well */
+#ifdef AGING
+ /*
+ * Have to do this while we still have root privileges, otherwise
+ * we don't have access to /etc/shadow. expire() closes password
+ * files, and changes to the user in the child before executing
+ * the passwd program. --marekm
+ */
+#ifdef SHADOWPWD
+ if (spwd) { /* check for age of password */
+ if (expire (&pwent, spwd)) {
+ pwd = getpwnam(username);
+ spwd = getspnam(username);
+ if (pwd)
+ pwent = *pwd;
+ }
+ }
+#else
+#ifdef ATT_AGE
+ if (pwent.pw_age && pwent.pw_age[0]) {
+ if (expire (&pwent)) {
+ pwd = getpwnam(username);
+ if (pwd)
+ pwent = *pwd;
+ }
+ }
+#endif /* ATT_AGE */
+#endif /* SHADOWPWD */
+#endif /* AGING */
+
+#ifdef RADIUS
+ if (is_rad_login) {
+ char whofilename[128];
+ FILE *whofile;
+
+ snprintf(whofilename, sizeof whofilename, "/var/log/radacct/%.20s", tty);
+ whofile = fopen(whofilename, "w");
+ if (whofile) {
+ fprintf(whofile, "%s\n", username);
+ fclose(whofile);
+ }
+ }
+#endif
+ setup_limits(&pwent); /* nice, ulimit etc. */
+#endif /* ! USE_PAM */
+ chown_tty(tty, &pwent);
+
+#ifdef LOGIN_FBTAB
+ /*
+ * XXX - not supported yet. Change permissions and ownerships of
+ * devices like floppy/audio/mouse etc. for console logins, based
+ * on /etc/fbtab or /etc/logindevperm configuration files (Suns do
+ * this with their framebuffer devices). Problems:
+ *
+ * - most systems (except BSD) don't have that nice revoke() system
+ * call to ensure the previous user didn't leave a process holding
+ * one of these devices open or mmap'ed. Any volunteers to do it
+ * in Linux?
+ *
+ * - what to do with different users logged in on different virtual
+ * consoles? Maybe permissions should be changed only on user's
+ * request, by running a separate (setuid root) program?
+ *
+ * - init/telnetd/rlogind/whatever should restore permissions after
+ * the user logs out.
+ *
+ * Try the new CONSOLE_GROUPS feature instead. It adds specified
+ * groups (like "floppy") to the group set if the user is logged in
+ * on the console. This still has the first problem (users leaving
+ * processes with these devices open), but doesn't need to change
+ * any permissions, just make them 0660 root:floppy etc. --marekm
+ *
+ * Warning: users can still gain permanent access to these groups
+ * unless any user-writable filesystems are mounted with the "nosuid"
+ * option. Alternatively, the kernel could be modified to prevent
+ * ordinary users from setting the setgid bit on executables.
+ */
+ login_fbtab(tty, pwent.pw_uid, pwent.pw_gid);
+#endif
+
+ /* We call set_groups() above because this clobbers pam_groups.so */
+#ifndef USE_PAM
+ if (setup_uid_gid(&pwent, is_console))
+#else
+ if (change_uid(&pwent))
+#endif
+ exit(1);
+
+#ifdef KERBEROS
+ if (clear_pass)
+ login_kerberos(username, clear_pass);
+#endif
+#ifdef DES_RPC
+ if (clear_pass)
+ login_desrpc(clear_pass);
+#endif
+#if defined(DES_RPC) || defined(KERBEROS)
+ if (clear_pass)
+ strzero(clear_pass);
+#endif
+
+ setup_env(&pwent); /* set env vars, cd to the home dir */
+
+#ifdef USE_PAM
+ {
+ int i;
+ const char * const * env;
+
+ env = (const char * const *) pam_getenvlist(pamh);
+ while (env && *env) {
+ addenv(*env, NULL);
+ env++;
+ }
+ }
+#endif
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (!hushed(&pwent)) {
+ addenv("HUSHLOGIN=FALSE", NULL);
+ /* pam_unix, pam_mail and pam_lastlog should take care of this */
+#ifndef USE_PAM
+ motd(); /* print the message of the day */
+ if (getdef_bool("FAILLOG_ENAB") && faillog.fail_cnt != 0) {
+ failprint(&faillog);
+ /* Reset the lockout times if logged in */
+ if (faillog.fail_max &&
+ faillog.fail_cnt >= faillog.fail_max) {
+ puts(_("Warning: login re-enabled after temporary lockout.\n"));
+ SYSLOG((LOG_WARN, REENABLED2, username,
+ (int) faillog.fail_cnt));
+ }
+ }
+ if (getdef_bool("LASTLOG_ENAB") && lastlog.ll_time != 0) {
+#ifdef HAVE_STRFTIME
+ strftime(ptime, sizeof(ptime),
+ "%a %b %e %H:%M:%S %z %Y",
+ localtime(&lastlog.ll_time));
+ printf(_("Last login: %s on %s"),
+ ptime, lastlog.ll_line);
+#else
+ printf(_("Last login: %.19s on %s"),
+ ctime(&lastlog.ll_time), lastlog.ll_line);
+#endif
+#ifdef HAVE_LL_HOST /* SVR4 || __linux__ || SUN4 */
+ if (lastlog.ll_host[0])
+ printf(_(" from %.*s"),
+ (int) sizeof lastlog.ll_host,
+ lastlog.ll_host);
+#endif
+ printf(".\n");
+ }
+#ifdef AGING
+#ifdef SHADOWPWD
+ agecheck(&pwent, spwd);
+#else
+ agecheck(&pwent);
+#endif
+#endif /* AGING */
+ mailcheck(); /* report on the status of mail */
+#endif /* !USE_PAM */
+ } else
+ addenv("HUSHLOGIN=TRUE", NULL);
+
+ if (getdef_str("TTYTYPE_FILE") != NULL && getenv("TERM") == NULL)
+ ttytype (tty);
+
+ signal(SIGQUIT, SIG_DFL); /* default quit signal */
+ signal(SIGTERM, SIG_DFL); /* default terminate signal */
+ signal(SIGALRM, SIG_DFL); /* default alarm signal */
+ signal(SIGHUP, SIG_DFL); /* added this. --marekm */
+
+#ifdef USE_PAM
+ /* We must fork before setuid() because we need to call
+ * pam_close_session() as root.
+ */
+ /* Note: not true in other (non-Linux) PAM implementations, where
+ the parent process of login (init, telnetd, ...) is responsible
+ for calling pam_close_session(). This avoids an extra process
+ for each login. Maybe we should do this on Linux too? -MM */
+ /* We let the admin configure whether they need to keep login
+ around to close sessions */
+ if (getdef_bool("CLOSE_SESSIONS")) {
+ signal(SIGINT, SIG_IGN);
+ child = fork();
+ if (child < 0) {
+ /* error in fork() */
+ fprintf(stderr, "login: failure forking: %s",
+ strerror(errno));
+ PAM_END;
+ exit(0);
+ } else if (child) {
+ /* parent - wait for child to finish,
+ then cleanup session */
+ wait(NULL);
+ PAM_END;
+ exit(0);
+ }
+ /* child */
+ }
+#endif
+ signal(SIGINT, SIG_DFL); /* default interrupt signal */
+
+ endpwent(); /* stop access to password file */
+ endgrent(); /* stop access to group file */
+#ifdef SHADOWPWD
+ endspent(); /* stop access to shadow passwd file */
+#endif
+#ifdef SHADOWGRP
+ endsgent(); /* stop access to shadow group file */
+#endif
+ if (pwent.pw_uid == 0)
+ SYSLOG((LOG_NOTICE, ROOT_LOGIN, fromhost));
+ else if (getdef_bool("LOG_OK_LOGINS"))
+ SYSLOG((LOG_INFO, REG_LOGIN, username, fromhost));
+ closelog();
+#ifdef RADIUS
+ if (is_rad_login) {
+ printf(_("Starting rad_login\n"));
+ rad_login(&rad_user_data);
+ exit(0);
+ }
+#endif
+ if ((tmp = getdef_str("FAKE_SHELL")) != NULL) {
+ shell(tmp, pwent.pw_shell); /* fake shell */
+ }
+ shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
+ /*NOTREACHED*/
+ return 0;
+}
diff --git a/current/src/logoutd.c b/current/src/logoutd.c
new file mode 100644
index 00000000..7d5ee566
--- /dev/null
+++ b/current/src/logoutd.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 1991 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: logoutd.c,v 1.16 2000/09/02 18:40:44 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <signal.h>
+#include <utmp.h>
+#include <fcntl.h>
+#include "prototypes.h"
+#include "defines.h"
+
+#ifdef SVR4
+#include <libgen.h>
+#endif
+
+#ifdef SVR4
+#define signal sigset
+#endif
+
+static char *Prog;
+
+#ifndef DEFAULT_HUP_MESG
+#define DEFAULT_HUP_MESG "login time exceeded\r\n"
+#endif
+
+#ifndef HUP_MESG_FILE
+#define HUP_MESG_FILE "/etc/logoutd.mesg"
+#endif
+
+/* local function prototypes */
+static int check_login(const struct utmp *);
+
+
+/*
+ * check_login - check if user (struct utmp) allowed to stay logged in
+ */
+static int
+check_login(const struct utmp *ut)
+{
+ char user[sizeof(ut->ut_user) + 1];
+ time_t now;
+
+ /*
+ * ut_user may not have the terminating NUL.
+ */
+ strncpy(user, ut->ut_user, sizeof(ut->ut_user));
+ user[sizeof(ut->ut_user)] = '\0';
+
+ time(&now);
+
+ /*
+ * Check if they are allowed to be logged in right now.
+ */
+ if (!isttytime(user, ut->ut_line, now))
+ return 0;
+#if 0
+ /*
+ * Check for how long they are allowed to stay logged in.
+ * XXX - not implemented yet. Need to add a new field to
+ * /etc/porttime (login time limit in minutes, or no limit,
+ * based on username, tty, and time of login).
+ */
+ if (now - ut->ut_time > get_time_limit(user, ut->ut_line, ut->ut_time))
+ return 0;
+#endif
+ return 1;
+}
+
+
+static void
+send_mesg_to_tty(int tty_fd)
+{
+ TERMIO oldt, newt;
+ FILE *mesg_file, *tty_file;
+ int c, is_tty;
+
+ tty_file = fdopen(tty_fd, "w");
+ if (!tty_file)
+ return;
+
+ is_tty = (GTTY(tty_fd, &oldt) == 0);
+ if (is_tty) {
+ /* Suggested by Ivan Nejgebauar <ian@unsux.ns.ac.yu>:
+ set OPOST before writing the message. */
+ newt = oldt;
+ newt.c_oflag |= OPOST;
+ STTY(tty_fd, &newt);
+ }
+
+ mesg_file = fopen(HUP_MESG_FILE, "r");
+ if (mesg_file) {
+ while ((c = getc(mesg_file)) != EOF) {
+ if (c == '\n')
+ putc('\r', tty_file);
+ putc(c, tty_file);
+ }
+ fclose(mesg_file);
+ } else {
+ fputs(DEFAULT_HUP_MESG, tty_file);
+ }
+ fflush(tty_file);
+ fclose(tty_file);
+
+ if (is_tty) {
+ STTY(tty_fd, &oldt);
+ }
+}
+
+
+/*
+ * logoutd - logout daemon to enforce /etc/porttime file policy
+ *
+ * logoutd is started at system boot time and enforces the login
+ * time and port restrictions specified in /etc/porttime. The
+ * utmp file is periodically scanned and offending users are logged
+ * off from the system.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int i;
+ int status;
+ pid_t pid;
+ struct utmp *ut;
+ char user[sizeof(ut->ut_user) + 1]; /* terminating NUL */
+ char tty_name[sizeof(ut->ut_line) + 6]; /* /dev/ + NUL */
+ int tty_fd;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+#ifndef DEBUG
+ for (i = 0;close (i) == 0;i++)
+ ;
+
+#ifdef HAVE_SETPGRP
+#ifdef SETPGRP_VOID
+ setpgrp(); /* USG */
+#else
+ setpgrp(getpid(), getpid());
+#endif
+#else /* !HAVE_SETPGRP */
+ setpgid(getpid(), getpid()); /* BSD || SUN || SUN4 */
+#endif /* !HAVE_SETPGRP */
+
+ /*
+ * Put this process in the background.
+ */
+
+ pid = fork();
+ if (pid > 0) {
+ /* parent */
+ exit(0);
+ } else if (pid < 0) {
+ /* error */
+ perror("fork");
+ exit(1);
+ }
+#endif /* !DEBUG */
+
+ /*
+ * Start syslogging everything
+ */
+
+ Prog = Basename(argv[0]);
+
+ OPENLOG(Prog);
+
+ /*
+ * Scan the UTMP file once per minute looking for users that
+ * are not supposed to still be logged in.
+ */
+
+ while (1) {
+
+ /*
+ * Attempt to re-open the utmp file. The file is only
+ * open while it is being used.
+ */
+
+ setutent();
+
+ /*
+ * Read all of the entries in the utmp file. The entries
+ * for login sessions will be checked to see if the user
+ * is permitted to be signed on at this time.
+ */
+
+ while ((ut = getutent())) {
+#ifdef USER_PROCESS
+ if (ut->ut_type != USER_PROCESS)
+ continue;
+#endif
+ if (ut->ut_user[0] == '\0')
+ continue;
+ if (check_login(ut))
+ continue;
+
+ /*
+ * Put the rest of this in a child process. This
+ * keeps the scan from waiting on other ports to die.
+ */
+
+ pid = fork();
+ if (pid > 0) {
+ /* parent */
+ continue;
+ } else if (pid < 0) {
+ /* failed - give up until the next scan */
+ break;
+ }
+ /* child */
+
+ if (strncmp(ut->ut_line, "/dev/", 5) != 0)
+ strcpy(tty_name, "/dev/");
+ else
+ tty_name[0] = '\0';
+
+ strcat(tty_name, ut->ut_line);
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+ tty_fd = open(tty_name, O_WRONLY|O_NDELAY|O_NOCTTY);
+ if (tty_fd != -1) {
+ send_mesg_to_tty(tty_fd);
+ close(tty_fd);
+ sleep(10);
+ }
+#ifdef USER_PROCESS /* USG_UTMP */
+ if (ut->ut_pid > 1) {
+ kill(- ut->ut_pid, SIGHUP);
+ sleep(10);
+ kill(- ut->ut_pid, SIGKILL);
+ }
+#else /* BSD || SUN || SUN4 */
+ /*
+ * vhangup() the line to kill try and kill
+ * whatever is out there using it.
+ */
+
+ if ((tty_fd = open (tty_name, O_RDONLY|O_NDELAY)) == -1)
+ continue;
+
+ vhangup (tty_fd);
+ close (tty_fd);
+#endif /* BSD || SUN || SUN4 */
+
+ strncpy(user, ut->ut_line, sizeof(user) - 1);
+ user[sizeof(user) - 1] = '\0';
+
+ SYSLOG((LOG_NOTICE, "logged off user `%s' on `%s'\n",
+ user, tty_name));
+
+ /*
+ * This child has done all it can, drop dead.
+ */
+
+ exit (0);
+ }
+
+ endutent();
+
+#ifndef DEBUG
+ sleep(60);
+#endif
+ /*
+ * Reap any dead babies ...
+ */
+
+ while (wait (&status) != -1)
+ ;
+ }
+ return 1; /* not reached */
+}
diff --git a/current/src/mkpasswd.c b/current/src/mkpasswd.c
new file mode 100644
index 00000000..e35da31f
--- /dev/null
+++ b/current/src/mkpasswd.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: mkpasswd.c,v 1.7 2000/08/26 18:27:18 marekm Exp $")
+
+#include <sys/stat.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <stdio.h>
+
+#if !defined(NDBM) /*{*/
+int
+main(int argc, char **argv)
+{
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ fprintf(stderr,
+ _("%s: no DBM database on system - no action performed\n"),
+ argv[0]);
+ return 0;
+}
+
+#else /*} defined(NDBM) {*/
+
+#include <fcntl.h>
+#include <pwd.h>
+
+#include <ndbm.h>
+#include <grp.h>
+
+extern DBM *pw_dbm;
+extern DBM *gr_dbm;
+#ifdef SHADOWPWD
+extern DBM *sp_dbm;
+#endif
+#ifdef SHADOWGRP
+extern DBM *sg_dbm;
+#endif
+char *fgetsx();
+
+#ifdef SHADOWPWD
+#ifdef SHADOWGRP
+#define USAGE _("Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n")
+#else /* !SHADOWGRP */
+#define USAGE _("Usage: %s [ -vf ] [ -p|g|sp ] file\n")
+#endif /* SHADOWGRP */
+#else /* !SHADOWPWD */
+#define USAGE _("Usage: %s [ -vf ] [ -p|g ] file\n")
+#endif /* SHADOWPWD */
+
+char *Progname;
+int vflg = 0;
+int fflg = 0;
+int gflg = 0;
+int sflg = 0; /* -s flag -- leave in, makes code nicer */
+int pflg = 0;
+
+extern struct passwd *sgetpwent();
+extern int pw_dbm_update();
+
+extern struct group *sgetgrent();
+extern int gr_dbm_update();
+
+#ifdef SHADOWPWD
+extern struct spwd *sgetspent();
+extern int sp_dbm_update();
+#endif
+
+#ifdef SHADOWGRP
+extern struct sgrp *sgetsgent();
+extern int sg_dbm_update();
+#endif
+
+/* local function prototypes */
+static void usage(void);
+
+/*
+ * mkpasswd - create DBM files for /etc/passwd-like input file
+ *
+ * mkpasswd takes an an argument the name of a file in /etc/passwd format
+ * and creates a DBM file keyed by user ID and name. The output files have
+ * the same name as the input file, with .dir and .pag appended.
+ *
+ * this command will also create look-aside files for
+ * /etc/group, /etc/shadow, and /etc/gshadow.
+ */
+
+int
+main(int argc, char **argv)
+{
+ extern int optind;
+ extern char *optarg;
+ FILE *fp; /* File pointer for input file */
+ char *file; /* Name of input file */
+ char *dir; /* Name of .dir file */
+ char *pag; /* Name of .pag file */
+ char *cp; /* Temporary character pointer */
+ int flag; /* Flag for command line option */
+ int cnt = 0; /* Number of entries in database */
+ int longest = 0; /* Longest entry in database */
+ int len; /* Length of input line */
+ int errors = 0; /* Count of errors processing file */
+ char buf[BUFSIZ*8]; /* Input line from file */
+ struct passwd *passwd=NULL; /* Pointer to password file entry */
+
+ struct group *group=NULL; /* Pointer to group file entry */
+#ifdef SHADOWPWD
+ struct spwd *shadow=NULL; /* Pointer to shadow passwd entry */
+#endif
+#ifdef SHADOWGRP
+ struct sgrp *gshadow=NULL; /* Pointer to shadow group entry */
+#endif
+ DBM *dbm; /* Pointer to new NDBM files */
+ DBM *dbm_open(); /* Function to open NDBM files */
+
+ /*
+ * Figure out what my name is. I will use this later ...
+ */
+
+ Progname = Basename(argv[0]);
+
+ /*
+ * Figure out what the flags might be ...
+ */
+
+ while ((flag = getopt (argc, argv, "fvpgs")) != EOF) {
+ switch (flag) {
+ case 'v':
+ vflg++;
+ break;
+ case 'f':
+ fflg++;
+ break;
+ case 'g':
+ gflg++;
+#ifndef SHADOWGRP
+ if (sflg)
+ usage ();
+#endif
+ if (pflg)
+ usage ();
+
+ break;
+#if defined(SHADOWPWD) || defined(SHADOWGRP)
+ case 's':
+ sflg++;
+#ifndef SHADOWGRP
+ if (gflg)
+ usage ();
+#endif
+ break;
+#endif
+ case 'p':
+ pflg++;
+ if (gflg)
+ usage ();
+
+ break;
+ default:
+ usage();
+ }
+ }
+
+ /*
+ * Backwards compatibility fix for -p flag ...
+ */
+
+#ifdef SHADOWPWD
+ if (! sflg && ! gflg)
+#else
+ if (! gflg)
+#endif
+ pflg++;
+
+ /*
+ * The last and only remaining argument must be the file name
+ */
+
+ if (argc - 1 != optind)
+ usage ();
+
+ file = argv[optind];
+
+ if (! (fp = fopen (file, "r"))) {
+ fprintf (stderr, _("%s: cannot open file %s\n"), Progname, file);
+ exit (1);
+ }
+
+ /*
+ * Make the filenames for the two DBM files.
+ */
+
+ dir = xmalloc (strlen (file) + 5); /* space for .dir file */
+ strcat (strcpy (dir, file), ".dir");
+
+ pag = xmalloc (strlen (file) + 5); /* space for .pag file */
+ strcat (strcpy (pag, file), ".pag");
+
+ /*
+ * Remove existing files if requested.
+ */
+
+ if (fflg) {
+ (void) unlink (dir);
+ (void) unlink (pag);
+ }
+
+ /*
+ * Create the two DBM files - it is an error for these files
+ * to have existed already.
+ */
+
+ if (access(dir, F_OK) == 0) {
+ fprintf (stderr, _("%s: cannot overwrite file %s\n"), Progname, dir);
+ exit (1);
+ }
+ if (access(pag, F_OK) == 0) {
+ fprintf (stderr, _("%s: cannot overwrite file %s\n"), Progname, pag);
+ exit (1);
+ }
+
+ if (sflg)
+ umask(077);
+ else
+ umask(022);
+
+ /*
+ * Now the DBM database gets initialized
+ */
+
+ if (! (dbm = dbm_open (file, O_RDWR|O_CREAT, 0644))) {
+ fprintf (stderr, _("%s: cannot open DBM files for %s\n"), Progname, file);
+ exit (1);
+ }
+ if (gflg) {
+#ifdef SHADOWGRP
+ if (sflg)
+ sg_dbm = dbm;
+ else
+#endif
+ gr_dbm = dbm;
+ } else {
+#ifdef SHADOWPWD
+ if (sflg)
+ sp_dbm = dbm;
+ else
+#endif
+ pw_dbm = dbm;
+ }
+
+ /*
+ * Read every line in the password file and convert it into a
+ * data structure to be put in the DBM database files.
+ */
+
+ while (fgetsx (buf, BUFSIZ, fp) != NULL) {
+
+ /*
+ * Get the next line and strip off the trailing newline
+ * character.
+ */
+
+ buf[sizeof buf - 1] = '\0';
+ if (! (cp = strchr (buf, '\n'))) {
+ fprintf (stderr, _("%s: the beginning with "%.16s ..." is too long\n"), Progname, buf);
+ exit (1);
+ }
+ *cp = '\0';
+ len = strlen (buf);
+
+#ifdef USE_NIS
+ /*
+ * Parse the password file line into a (struct passwd).
+ * Erroneous lines cause error messages, but that's
+ * all. YP lines are ignored completely.
+ */
+
+ if (buf[0] == '-' || buf[0] == '+')
+ continue;
+#endif
+ if (! (((! sflg && pflg) && (passwd = sgetpwent (buf)))
+#ifdef SHADOWPWD
+ || ((sflg && pflg) && (shadow = sgetspent (buf)))
+#endif
+ || ((! sflg && gflg) && (group = sgetgrent (buf)))
+#ifdef SHADOWGRP
+ || ((sflg && gflg) && (gshadow = sgetsgent (buf)))
+#endif
+ )) {
+ fprintf (stderr, _("%s: error parsing line \"%s\"\n"), Progname, buf);
+ errors++;
+ continue;
+ }
+ if (vflg) {
+ if (!sflg && pflg) printf (_("adding record for name "%s"\n"), passwd->pw_name);
+#ifdef SHADOWPWD
+ if (sflg && pflg) printf (_("adding record for name "%s"\n"), shadow->sp_namp);
+#endif
+ if (!sflg && gflg) printf (_("adding record for name "%s"\n"), group->gr_name);
+#ifdef SHADOWGRP
+ if (sflg && gflg) printf (_("adding record for name "%s"\n"), gshadow->sg_name);
+#endif
+ }
+ if (! sflg && pflg && ! pw_dbm_update (passwd))
+ fprintf (stderr, _("%s: error adding record for "%s"\n"),
+ Progname, passwd->pw_name);
+
+#ifdef SHADOWPWD
+ if (sflg && pflg && ! sp_dbm_update (shadow))
+ fprintf (stderr, _("%s: error adding record for "%s"\n"),
+ Progname, shadow->sp_namp);
+#endif
+ if (! sflg && gflg && ! gr_dbm_update (group))
+ fprintf (stderr, _("%s: error adding record for "%s"\n"),
+ Progname, group->gr_name);
+#ifdef SHADOWGRP
+ if (sflg && gflg && ! sg_dbm_update (gshadow))
+ fprintf (stderr, _("%s: error adding record for "%s"\n"),
+ Progname, gshadow->sg_name);
+#endif /* SHADOWGRP */
+
+ /*
+ * Update the longest record and record count
+ */
+
+ if (len > longest)
+ longest = len;
+ cnt++;
+ }
+
+ /*
+ * Tell the user how things went ...
+ */
+
+ if (vflg)
+ printf (_("added %d entries, longest was %d\n"), cnt, longest);
+
+ exit (errors);
+ /*NOTREACHED*/
+}
+
+/*
+ * usage - print error message and exit
+ */
+
+static void
+usage(void)
+{
+#ifdef SHADOWPWD
+#ifdef SHADOWGRP
+ fprintf (stderr, _("Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"), Progname);
+#else /* !SHADOWGRP */
+ fprintf (stderr, _("Usage: %s [ -vf ] [ -p|g|sp ] file\n"), Progname);
+#endif /* SHADOWGRP */
+#else /* !SHADOWPWD */
+ fprintf (stderr, _("Usage: %s [ -vf ] [ -p|g ] file\n"), Progname);
+#endif /* SHADOWPWD */
+
+
+ exit (1);
+ /*NOTREACHED*/
+}
+#endif /*} defined(NDBM) */
diff --git a/current/src/newgrp.c b/current/src/newgrp.c
new file mode 100644
index 00000000..9eb2c5bf
--- /dev/null
+++ b/current/src/newgrp.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright 1990 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: newgrp.c,v 1.16 2000/09/02 18:40:44 marekm Exp $")
+
+#include <stdio.h>
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include "getdef.h"
+
+extern char **environ;
+
+#ifdef HAVE_SETGROUPS
+static int ngroups;
+static GETGROUPS_T *grouplist;
+#endif
+
+static char *Prog;
+static int is_newgrp;
+
+/* local function prototypes */
+static void usage(void);
+
+/*
+ * usage - print command usage message
+ */
+
+static void
+usage(void)
+{
+ if (is_newgrp)
+ fprintf (stderr, _("usage: newgrp [ - ] [ group ]\n"));
+ else
+ fprintf (stderr, _("usage: sg group [[-c] command ]\n"));
+}
+
+/*
+ * newgrp - change the invokers current real and effective group id
+ */
+
+int
+main(int argc, char **argv)
+{
+ int initflag = 0;
+ int needspasswd = 0;
+ int i;
+ int their_grp = 0;
+ int cflag = 0;
+ gid_t gid;
+ char *cp;
+ const char *cpasswd, *name, *prog;
+ char *group = NULL;
+ char *command=NULL;
+ char **envp = environ;
+ struct passwd *pwd;
+ struct group *grp;
+#ifdef SHADOWPWD
+ struct spwd *spwd;
+#endif
+#ifdef SHADOWGRP
+ struct sgrp *sgrp;
+#endif
+
+#if ENABLE_NLS
+ /* XXX - remove when gettext is safe to use in setuid programs */
+ sanitize_env();
+#endif
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /*
+ * save my name for error messages and save my real gid incase
+ * of errors. if there is an error i have to exec a new login
+ * shell for the user since her old shell won't have fork'd to
+ * create the process. skip over the program name to the next
+ * command line argument.
+ */
+
+ Prog = Basename(argv[0]);
+ is_newgrp = (strcmp(Prog, "newgrp") == 0);
+ OPENLOG(is_newgrp ? "newgrp" : "sg");
+ gid = getgid();
+ argc--; argv++;
+
+ initenv();
+
+ pwd = get_my_pwent();
+ if (!pwd) {
+ fprintf (stderr, _("unknown uid: %d\n"), (int) getuid());
+ SYSLOG((LOG_WARN, "unknown uid %d\n", (int) getuid()));
+ closelog();
+ exit(1);
+ }
+ name = pwd->pw_name;
+
+ /*
+ * Parse the command line. There are two accepted flags. The
+ * first is "-", which for newgrp means to re-create the entire
+ * environment as though a login had been performed, and "-c",
+ * which for sg causes a command string to be executed.
+ *
+ * The next argument, if present, must be the new group name.
+ * Any remaining remaining arguments will be used to execute a
+ * command as the named group. If the group name isn't present,
+ * I just use the login group ID of the current user.
+ *
+ * The valid syntax are
+ * newgrp [ - ] [ groupid ]
+ * newgrp [ -l ] [ groupid ]
+ * sg [ - ]
+ * sg [ - ] groupid [ command ]
+ */
+
+ if (argc > 0 && (!strcmp(argv[0], "-") || !strcmp(argv[0], "-l"))) {
+ argc--; argv++;
+ initflag = 1;
+ }
+ if (!is_newgrp) {
+ /*
+ * Do the command line for everything that is
+ * not "newgrp".
+ */
+
+ if (argc > 0 && argv[0][0] != '-') {
+ group = argv[0];
+ argc--; argv++;
+ } else {
+ usage ();
+ closelog();
+ exit (1);
+ }
+ if (argc > 0) {
+
+ /* skip -c if specified so both forms work:
+ "sg group -c command" (as in the man page) or
+ "sg group command" (as in the usage message). */
+
+ if (argc > 1 && strcmp(argv[0], "-c") == 0)
+ command = argv[1];
+ else
+ command = argv[0];
+ cflag++;
+ }
+ } else {
+
+ /*
+ * Do the command line for "newgrp". It's just
+ * making sure there aren't any flags and getting
+ * the new group name.
+ */
+
+ if (argc > 0 && argv[0][0] == '-') {
+ usage ();
+ goto failure;
+ } else if (argv[0] != (char *) 0) {
+ group = argv[0];
+ } else {
+
+ /*
+ * get the group file entry for her login group id.
+ * the entry must exist, simply to be annoying.
+ */
+
+ if (! (grp = getgrgid (pwd->pw_gid))) {
+ fprintf(stderr, _("unknown gid: %ld\n"),
+ (long) pwd->pw_gid);
+ SYSLOG((LOG_CRIT, "unknown gid: %ld\n",
+ (long) pwd->pw_gid));
+ goto failure;
+ }
+ }
+ }
+
+#ifdef HAVE_SETGROUPS
+ /*
+ * get the current users groupset. the new group will be
+ * added to the concurrent groupset if there is room, otherwise
+ * you get a nasty message but at least your real and effective
+ * group id's are set.
+ */
+
+ /* don't use getgroups(0, 0) - it doesn't work on some systems */
+ i = 16;
+ for (;;) {
+ grouplist = (GETGROUPS_T *) xmalloc(i * sizeof(GETGROUPS_T));
+ ngroups = getgroups(i, grouplist);
+ if (i > ngroups && !(ngroups == -1 && errno == EINVAL))
+ break;
+ /* not enough room, so try allocating a larger buffer */
+ free(grouplist);
+ i *= 2;
+ }
+ if (ngroups < 0) {
+ perror("getgroups");
+ exit(1);
+ }
+#endif /* HAVE_SETGROUPS */
+
+ /*
+ * now we put her in the new group. the password file entry for
+ * her current user id has been gotten. if there was no optional
+ * group argument she will have her real and effective group id
+ * set to the value from her password file entry. otherwise
+ * we validate her access to the specified group.
+ */
+
+ if (group == (char *) 0) {
+ if (! (grp = getgrgid (pwd->pw_gid))) {
+ fprintf (stderr, _("unknown gid: %d\n"), pwd->pw_gid);
+ goto failure;
+ }
+ group = grp->gr_name;
+ their_grp = 1;
+ } else if (! (grp = getgrnam (group))) {
+ fprintf (stderr, _("unknown group: %s\n"), group);
+ goto failure;
+ }
+#ifdef SHADOWGRP
+ if ((sgrp = getsgnam (group))) {
+ grp->gr_passwd = sgrp->sg_passwd;
+ grp->gr_mem = sgrp->sg_mem;
+ }
+#endif
+
+ /*
+ * see if she is a member of this group.
+ * if she isn't a member, she needs to provide the
+ * group password. if there is no group password, she
+ * will be denied access anyway.
+ *
+ * we also check if this is the users default group, eg.
+ * they aren't a member, but this is the group listed as
+ * the one they belong to in their pwd entry.
+ */
+
+ if (!is_on_list(grp->gr_mem, name) && !their_grp)
+ needspasswd = 1;
+
+ /*
+ * if she does not have either a shadowed password,
+ * or a regular password, and the group has a password,
+ * she needs to give the group password.
+ */
+
+#ifdef SHADOWPWD
+ if ((spwd = getspnam (name)))
+ pwd->pw_passwd = spwd->sp_pwdp;
+#endif
+
+ if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
+ needspasswd = 1;
+
+ /*
+ * now i see about letting her into the group she requested.
+ * if she is the root user, i'll let her in without having to
+ * prompt for the password. otherwise i ask for a password
+ * if she flunked one of the tests above. note that she
+ * won't have to provide the password to her login group even
+ * if she isn't listed as a member.
+ */
+
+ if (getuid () != 0 && needspasswd) {
+
+ /*
+ * get the password from her, and set the salt for
+ * the decryption from the group file.
+ */
+
+ if (! (cp = getpass (_("Password: "))))
+ goto failure;
+
+ /*
+ * encrypt the key she gave us using the salt from
+ * the password in the group file. the result of
+ * this encryption must match the previously
+ * encrypted value in the file.
+ */
+
+ cpasswd = pw_encrypt (cp, grp->gr_passwd);
+ strzero(cp);
+
+ if (grp->gr_passwd[0] == '\0') {
+ /*
+ * there is no password, print out "Sorry" and give up
+ */
+ sleep(1);
+ fputs (_("Sorry.\n"), stderr);
+ goto failure;
+ }
+
+ if (strcmp (cpasswd, grp->gr_passwd) != 0) {
+ SYSLOG((LOG_INFO,
+ "Invalid password for group `%s' from `%s'\n",
+ group, name));
+ sleep(1);
+ fputs (_("Sorry.\n"), stderr);
+ goto failure;
+ }
+ }
+
+ /*
+ * all successful validations pass through this point. the
+ * group id will be set, and the group added to the concurrent
+ * groupset.
+ */
+
+#ifdef USE_SYSLOG
+ if (getdef_bool ("SYSLOG_SG_ENAB"))
+ SYSLOG((LOG_INFO, "user `%s' switched to group `%s'\n",
+ name, group));
+#endif
+ gid = grp->gr_gid;
+
+#ifdef HAVE_SETGROUPS
+ /*
+ * i am going to try to add her new group id to her concurrent
+ * group set. if the group id is already present i'll just
+ * skip this part. if the group doesn't fit, i'll complain
+ * loudly and skip this part ...
+ */
+
+ for (i = 0;i < ngroups;i++) {
+ if (gid == grouplist[i])
+ break;
+ }
+ if (i == ngroups) {
+ if (ngroups >= NGROUPS_MAX) {
+ fprintf (stderr, _("too many groups\n"));
+ } else {
+ grouplist[ngroups++] = gid;
+ if (setgroups(ngroups, grouplist)) {
+ perror("setgroups");
+ }
+ }
+ }
+#endif
+
+okay:
+ /*
+ * i set her group id either to the value she requested, or
+ * to the original value if the newgrp failed.
+ */
+
+ if (setgid(gid))
+ perror("setgid");
+
+ if (setuid(getuid())) {
+ perror("setuid");
+ exit(1);
+ }
+
+ /*
+ * see if the "-c" flag was used. if it was, i just create a
+ * shell command for her using the argument that followed the
+ * "-c" flag.
+ */
+
+ if (cflag) {
+ closelog();
+ execl("/bin/sh", "sh", "-c", command, (char *) 0);
+ if (errno == ENOENT) {
+ perror("/bin/sh");
+ exit(127);
+ } else {
+ perror("/bin/sh");
+ exit(126);
+ }
+ }
+
+ /*
+ * i have to get the pathname of her login shell. as a favor,
+ * i'll try her environment for a $SHELL value first, and
+ * then try the password file entry. obviously this shouldn't
+ * be in the restricted command directory since it could be
+ * used to leave the restricted environment.
+ */
+
+ if (! initflag && (cp = getenv ("SHELL")))
+ prog = cp;
+ else if (pwd->pw_shell && pwd->pw_shell[0])
+ prog = pwd->pw_shell;
+ else
+ prog = "/bin/sh";
+
+ /*
+ * now i try to find the basename of the login shell. this
+ * will become argv[0] of the spawned command.
+ */
+
+ cp = Basename((char *) prog);
+
+#ifdef SHADOWPWD
+ endspent ();
+#endif
+#ifdef SHADOWGRP
+ endsgent ();
+#endif
+ endpwent ();
+ endgrent ();
+
+ /*
+ * switch back to her home directory if i am doing login
+ * initialization.
+ */
+
+ if (initflag) {
+ if (chdir (pwd->pw_dir))
+ perror("chdir");
+
+ while (*envp) {
+ if (strncmp (*envp, "PATH=", 5) == 0 ||
+ strncmp (*envp, "HOME=", 5) == 0 ||
+ strncmp (*envp, "SHELL=", 6) == 0 ||
+ strncmp (*envp, "TERM=", 5) == 0)
+ addenv(*envp, NULL);
+
+ envp++;
+ }
+ } else {
+ while (*envp)
+ addenv(*envp++, NULL);
+ }
+
+ /* sanitize_env() removes $HOME from the environment (maybe it
+ shouldn't - please tell me if you are sure that $HOME can't
+ cause security problems) - add it from user's passwd entry.
+ */
+ addenv("HOME", pwd->pw_dir);
+
+ /*
+ * exec the login shell and go away. we are trying to get
+ * back to the previous environment which should be the
+ * user's login shell.
+ */
+
+ shell(prog, initflag ? (char *)0 : cp);
+ /*NOTREACHED*/
+
+failure:
+ /*
+ * this is where all failures land. the group id will not
+ * have been set, so the setgid() below will set me to the
+ * original group id i had when i was invoked.
+ */
+
+ /*
+ * only newgrp needs to re-exec the user's shell. that is
+ * because the shell doesn't recognize "sg", so it doesn't
+ * "exec" this command.
+ */
+
+ if (!is_newgrp) {
+ closelog();
+ exit (1);
+ }
+
+ /*
+ * The GID is still set to the old value, so now I can
+ * give the user back her shell.
+ */
+
+ goto okay;
+}
diff --git a/current/src/newusers.c b/current/src/newusers.c
new file mode 100644
index 00000000..fd313c4b
--- /dev/null
+++ b/current/src/newusers.c
@@ -0,0 +1,568 @@
+/*
+ * Copyright 1990 - 1993, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * newusers - create users from a batch file
+ *
+ * newusers creates a collection of entries in /etc/passwd
+ * and related files by reading a passwd-format file and
+ * adding entries in the related directories.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: newusers.c,v 1.11 2000/08/26 18:27:18 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "prototypes.h"
+#include "defines.h"
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include <fcntl.h>
+
+static char *Prog;
+
+#include "getdef.h"
+#include "pwio.h"
+#include "groupio.h"
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+
+static int is_shadow;
+#endif
+
+/* local function prototypes */
+static void usage(void);
+static int add_group(const char *, const char *, gid_t *);
+static int add_user(const char *, const char *, uid_t *, gid_t);
+static void update_passwd(struct passwd *, const char *);
+static int add_passwd(struct passwd *, const char *);
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("Usage: %s [ input ]\n"), Prog);
+ exit(1);
+}
+
+/*
+ * add_group - create a new group or add a user to an existing group
+ */
+
+static int
+add_group(const char *name, const char *gid, gid_t *ngid)
+{
+ const struct passwd *pwd;
+ const struct group *grp;
+ struct group grent;
+ char *members[2];
+ int i;
+
+ /*
+ * Start by seeing if the named group already exists. This
+ * will be very easy to deal with if it does.
+ */
+
+ if ((grp = gr_locate (gid))) {
+add_member:
+ grent = *grp;
+ *ngid = grent.gr_gid;
+ for (i = 0;grent.gr_mem[i] != (char *) 0;i++)
+ if (strcmp (grent.gr_mem[i], name) == 0)
+ return 0;
+
+ grent.gr_mem = (char **) xmalloc (sizeof (char *) * (i + 2));
+ memcpy (grent.gr_mem, grp->gr_mem, sizeof (char *) * (i + 2));
+ grent.gr_mem[i] = xstrdup (name);
+ grent.gr_mem[i + 1] = (char *) 0;
+
+ return ! gr_update (&grent);
+ }
+
+ /*
+ * The group did not exist, so I try to figure out what the
+ * GID is going to be. The gid parameter is probably "", meaning
+ * I figure out the GID from the password file. I want the UID
+ * and GID to match, unless the GID is already used.
+ */
+
+ if (gid[0] == '\0') {
+ i = 100;
+ for (pw_rewind ();(pwd = pw_next ());) {
+ if (pwd->pw_uid >= i)
+ i = pwd->pw_uid + 1;
+ }
+ for (gr_rewind ();(grp = gr_next ());) {
+ if (grp->gr_gid == i) {
+ i = -1;
+ break;
+ }
+ }
+ } else if (gid[0] >= '0' && gid[0] <= '9') {
+
+ /*
+ * The GID is a number, which means either this is a brand new
+ * group, or an existing group. For existing groups I just add
+ * myself as a member, just like I did earlier.
+ */
+
+ i = atoi (gid);
+ for (gr_rewind ();(grp = gr_next ());)
+ if (grp->gr_gid == i)
+ goto add_member;
+ } else
+
+ /*
+ * The last alternative is that the GID is a name which is not
+ * already the name of an existing group, and I need to figure
+ * out what group ID that group name is going to have.
+ */
+
+ i = -1;
+
+ /*
+ * If I don't have a group ID by now, I'll go get the
+ * next one.
+ */
+
+ if (i == -1) {
+ for (i = 100, gr_rewind ();(grp = gr_next ());)
+ if (grp->gr_gid >= i)
+ i = grp->gr_gid + 1;
+ }
+
+ /*
+ * Now I have all of the fields required to create the new
+ * group.
+ */
+
+ if (gid[0] && (gid[0] <= '0' || gid[0] >= '9'))
+ grent.gr_name = xstrdup(gid);
+ else
+ grent.gr_name = xstrdup(name);
+
+ grent.gr_passwd = "x"; /* XXX warning: const */
+ grent.gr_gid = i;
+ members[0] = xstrdup(name);
+ members[1] = (char *) 0;
+ grent.gr_mem = members;
+
+ *ngid = grent.gr_gid;
+ return ! gr_update (&grent);
+}
+
+/*
+ * add_user - create a new user ID
+ */
+
+static int
+add_user(const char *name, const char *uid, uid_t *nuid, gid_t gid)
+{
+ const struct passwd *pwd;
+ struct passwd pwent;
+ uid_t i;
+
+ /*
+ * The first guess for the UID is either the numerical UID
+ * that the caller provided, or the next available UID.
+ */
+
+ if (uid[0] >= '0' && uid[0] <= '9') {
+ i = atoi (uid);
+ } else if (uid[0] && (pwd = pw_locate (uid))) {
+ i = pwd->pw_uid;
+ } else {
+ i = 100;
+ for (pw_rewind ();(pwd = pw_next ());)
+ if (pwd->pw_uid >= i)
+ i = pwd->pw_uid + 1;
+ }
+
+ /*
+ * I don't want to fill in the entire password structure
+ * members JUST YET, since there is still more data to be
+ * added. So, I fill in the parts that I have.
+ */
+
+ pwent.pw_name = xstrdup(name);
+ pwent.pw_passwd = "x"; /* XXX warning: const */
+#ifdef ATT_AGE
+ pwent.pw_age = "";
+#endif
+#ifdef ATT_COMMENT
+ pwent.pw_comment = "";
+#endif
+#ifdef BSD_QUOTA
+ pwent.pw_quota = 0;
+#endif
+ pwent.pw_uid = i;
+ pwent.pw_gid = gid;
+ pwent.pw_gecos = ""; /* XXX warning: const */
+ pwent.pw_dir = ""; /* XXX warning: const */
+ pwent.pw_shell = ""; /* XXX warning: const */
+
+ *nuid = i;
+ return ! pw_update (&pwent);
+}
+
+static void
+update_passwd(struct passwd *pwd, const char *passwd)
+{
+ pwd->pw_passwd = pw_encrypt(passwd, crypt_make_salt());
+#ifdef ATT_AGE
+ if (strlen(pwd->pw_age) == 4) {
+ static char newage[5];
+ extern char *l64a();
+
+ strcpy(newage, pwd->pw_age);
+ strcpy(newage + 2, l64a(time((time_t *) 0) / WEEK));
+ pwd->pw_age = newage;
+ }
+#endif
+}
+
+/*
+ * add_passwd - add or update the encrypted password
+ */
+
+static int
+add_passwd(struct passwd *pwd, const char *passwd)
+{
+#ifdef SHADOWPWD
+ const struct spwd *sp;
+ struct spwd spent;
+#endif
+
+ /*
+ * In the case of regular password files, this is real
+ * easy - pwd points to the entry in the password file.
+ * Shadow files are harder since there are zillions of
+ * things to do ...
+ */
+
+ if (!is_shadow) {
+ update_passwd(pwd, passwd);
+ return 0;
+ }
+
+#ifdef SHADOWPWD
+ /*
+ * Do the first and easiest shadow file case. The user
+ * already exists in the shadow password file.
+ */
+
+ if ((sp = spw_locate (pwd->pw_name))) {
+ spent = *sp;
+ spent.sp_pwdp = pw_encrypt(passwd, crypt_make_salt());
+ return ! spw_update (&spent);
+ }
+
+ /*
+ * Pick the next easiest case - the user has an encrypted
+ * password which isn't equal to "x". The password was set
+ * to "x" earlier when the entry was created, so this user
+ * would have to have had the password set someplace else.
+ */
+
+ if (strcmp (pwd->pw_passwd, "x") != 0) {
+ update_passwd(pwd, passwd);
+ return 0;
+ }
+
+ /*
+ * Now the really hard case - I need to create an entirely
+ * new shadow password file entry.
+ */
+
+ spent.sp_namp = pwd->pw_name;
+ spent.sp_pwdp = pw_encrypt(passwd, crypt_make_salt());
+ spent.sp_lstchg = time((time_t *) 0) / SCALE;
+ spent.sp_min = getdef_num("PASS_MIN_DAYS", 0);
+ /* 10000 is infinity this week */
+ spent.sp_max = getdef_num("PASS_MAX_DAYS", 10000);
+ spent.sp_warn = getdef_num("PASS_WARN_AGE", -1);
+ spent.sp_inact = -1;
+ spent.sp_expire = -1;
+ spent.sp_flag = -1;
+
+ return ! spw_update (&spent);
+#endif
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[BUFSIZ];
+ char *fields[8];
+ int nfields;
+ char *cp;
+ const struct passwd *pw;
+ struct passwd newpw;
+ int errors = 0;
+ int line = 0;
+ uid_t uid;
+ gid_t gid;
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc > 1 && argv[1][0] == '-')
+ usage ();
+
+ if (argc == 2) {
+ if (! freopen (argv[1], "r", stdin)) {
+ snprintf(buf, sizeof buf, "%s: %s", Prog, argv[1]);
+ perror (buf);
+ exit (1);
+ }
+ }
+
+ /*
+ * Lock the password files and open them for update. This will
+ * bring all of the entries into memory where they may be
+ * searched for an modified, or new entries added. The password
+ * file is the key - if it gets locked, assume the others can
+ * be locked right away.
+ */
+
+ if (!pw_lock()) {
+ fprintf (stderr, _("%s: can't lock /etc/passwd.\n"), Prog);
+ exit (1);
+ }
+#ifdef SHADOWPWD
+ is_shadow = spw_file_present();
+
+ if ((is_shadow && !spw_lock()) || !gr_lock())
+#else
+ if (!gr_lock())
+#endif
+ {
+ fprintf (stderr, _("%s: can't lock files, try again later\n"),
+ Prog);
+ (void) pw_unlock ();
+#ifdef SHADOWPWD
+ if (is_shadow)
+ spw_unlock();
+#endif
+ exit (1);
+ }
+#ifdef SHADOWPWD
+ if (!pw_open(O_RDWR) || (is_shadow && !spw_open(O_RDWR)) || !gr_open(O_RDWR))
+#else
+ if (!pw_open(O_RDWR) || !gr_open(O_RDWR))
+#endif
+ {
+ fprintf (stderr, _("%s: can't open files\n"), Prog);
+ (void) pw_unlock ();
+#ifdef SHADOWPWD
+ if (is_shadow)
+ spw_unlock();
+#endif
+ (void) gr_unlock ();
+ exit (1);
+ }
+
+ /*
+ * Read each line. The line has the same format as a password
+ * file entry, except that certain fields are not contrained to
+ * be numerical values. If a group ID is entered which does
+ * not already exist, an attempt is made to allocate the same
+ * group ID as the numerical user ID. Should that fail, the
+ * next available group ID over 100 is allocated. The pw_gid
+ * field will be updated with that value.
+ */
+
+ while (fgets (buf, sizeof buf, stdin) != (char *) 0) {
+ line++;
+ if ((cp = strrchr (buf, '\n'))) {
+ *cp = '\0';
+ } else {
+ fprintf (stderr, _("%s: line %d: line too long\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+
+ /*
+ * Break the string into fields and screw around with
+ * them. There MUST be 7 colon separated fields,
+ * although the values aren't that particular.
+ */
+
+ for (cp = buf, nfields = 0;nfields < 7;nfields++) {
+ fields[nfields] = cp;
+ if ((cp = strchr (cp, ':')))
+ *cp++ = '\0';
+ else
+ break;
+ }
+ if (nfields != 6) {
+ fprintf (stderr, _("%s: line %d: invalid line\n"),
+ Prog, line);
+ continue;
+ }
+
+ /*
+ * Now the fields are processed one by one. The first
+ * field to be processed is the group name. A new
+ * group will be created if the group name is non-numeric
+ * and does not already exist. The named user will be
+ * the only member. If there is no named group to be a
+ * member of, the UID will be figured out and that value
+ * will be a candidate for a new group, if that group ID
+ * exists, a whole new group ID will be made up.
+ */
+
+ if (! (pw = pw_locate (fields[0])) &&
+ add_group (fields[0], fields[3], &gid)) {
+ fprintf (stderr, _("%s: line %d: can't create GID\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+
+ /*
+ * Now we work on the user ID. It has to be specified
+ * either as a numerical value, or left blank. If it
+ * is a numerical value, that value will be used, otherwise
+ * the next available user ID is computed and used. After
+ * this there will at least be a (struct passwd) for the
+ * user.
+ */
+
+ if (! pw && add_user (fields[0], fields[2], &uid, gid)) {
+ fprintf (stderr, _("%s: line %d: can't create UID\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+
+ /*
+ * The password, gecos field, directory, and shell fields
+ * all come next.
+ */
+
+ if (! (pw = pw_locate (fields[0]))) {
+ fprintf (stderr, _("%s: line %d: cannot find user %s\n"),
+ Prog, line, fields[0]);
+ errors++;
+ continue;
+ }
+ newpw = *pw;
+
+ if (add_passwd (&newpw, fields[1])) {
+ fprintf (stderr, _("%s: line %d: can't update password\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+ if (fields[4][0])
+ newpw.pw_gecos = fields[4];
+
+ if (fields[5][0])
+ newpw.pw_dir = fields[5];
+
+ if (fields[6][0])
+ newpw.pw_shell = fields[6];
+
+ if (newpw.pw_dir[0] && access(newpw.pw_dir, F_OK)) {
+ if (mkdir (newpw.pw_dir,
+ 0777 & ~getdef_num("UMASK", 077)))
+ fprintf (stderr, _("%s: line %d: mkdir failed\n"),
+ Prog, line);
+ else if (chown (newpw.pw_dir,
+ newpw.pw_uid, newpw.pw_gid))
+ fprintf (stderr, _("%s: line %d: chown failed\n"),
+ Prog, line);
+ }
+
+ /*
+ * Update the password entry with the new changes made.
+ */
+
+ if (! pw_update (&newpw)) {
+ fprintf (stderr, _("%s: line %d: can't update entry\n"),
+ Prog, line);
+ errors++;
+ continue;
+ }
+ }
+
+ /*
+ * Any detected errors will cause the entire set of changes
+ * to be aborted. Unlocking the password file will cause
+ * all of the changes to be ignored. Otherwise the file is
+ * closed, causing the changes to be written out all at
+ * once, and then unlocked afterwards.
+ */
+
+ if (errors) {
+ fprintf (stderr, _("%s: error detected, changes ignored\n"), Prog);
+ (void) gr_unlock ();
+#ifdef SHADOWPWD
+ if (is_shadow)
+ spw_unlock();
+#endif
+ (void) pw_unlock ();
+ exit (1);
+ }
+#ifdef SHADOWPWD
+ if (!pw_close() || (is_shadow && !spw_close()) || !gr_close())
+#else
+ if (!pw_close() || ! gr_close())
+#endif
+ {
+ fprintf (stderr, _("%s: error updating files\n"), Prog);
+ (void) gr_unlock ();
+#ifdef SHADOWPWD
+ if (is_shadow)
+ spw_unlock();
+#endif
+ (void) pw_unlock ();
+ exit (1);
+ }
+ (void) gr_unlock ();
+#ifdef SHADOWPWD
+ if (is_shadow)
+ spw_unlock();
+#endif
+ (void) pw_unlock ();
+
+ exit (0);
+ /*NOTREACHED*/
+}
diff --git a/current/src/passwd.c b/current/src/passwd.c
new file mode 100644
index 00000000..b43eb78b
--- /dev/null
+++ b/current/src/passwd.c
@@ -0,0 +1,1415 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: passwd.c,v 1.20 2000/09/02 18:40:44 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include <sys/types.h>
+#include <time.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+
+#ifdef HAVE_USERSEC_H
+#include <userpw.h>
+#include <usersec.h>
+#include <userconf.h>
+#endif
+
+#ifndef GPASSWD_PROGRAM
+#define GPASSWD_PROGRAM "gpasswd"
+#endif
+
+#ifndef CHFN_PROGRAM
+#define CHFN_PROGRAM "chfn"
+#endif
+
+#ifndef CHSH_PROGRAM
+#define CHSH_PROGRAM "chsh"
+#endif
+
+#include <pwd.h>
+#ifndef HAVE_USERSEC_H
+#ifdef SHADOWPWD
+#ifndef AGING
+#define AGING 0
+#endif /* !AGING */
+#endif /* SHADOWPWD */
+#endif /* !HAVE_USERSEC_H */
+#include "pwauth.h"
+
+#ifdef HAVE_TCFS
+#include <tcfslib.h>
+#include "tcfsio.h"
+#endif
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+#include "pwio.h"
+#include "getdef.h"
+
+/*
+ * exit status values
+ */
+
+#define E_SUCCESS 0 /* success */
+#define E_NOPERM 1 /* permission denied */
+#define E_USAGE 2 /* invalid combination of options */
+#define E_FAILURE 3 /* unexpected failure, nothing done */
+#define E_MISSING 4 /* unexpected failure, passwd file missing */
+#define E_PWDBUSY 5 /* passwd file busy, try again later */
+#define E_BAD_ARG 6 /* invalid argument to option */
+
+/*
+ * Global variables
+ */
+
+#ifdef HAVE_USERSEC_H
+int minage = 0; /* Minimum age in weeks */
+int maxage = 10000; /* Maximum age in weeks */
+#endif
+
+static char *name; /* The name of user whose password is being changed */
+static char *myname; /* The current user's name */
+static char *Prog; /* Program name */
+static int amroot; /* The real UID was 0 */
+
+static int
+ lflg = 0, /* -l - lock account */
+ uflg = 0, /* -u - unlock account */
+ dflg = 0, /* -d - delete password */
+#ifdef AGING
+ xflg = 0, /* -x - set maximum days */
+ nflg = 0, /* -n - set minimum days */
+ eflg = 0, /* -e - force password change */
+ kflg = 0, /* -k - change only if expired */
+#endif
+#ifdef SHADOWPWD
+ wflg = 0, /* -w - set warning days */
+ iflg = 0, /* -i - set inactive days */
+#endif
+ qflg = 0, /* -q - quiet mode */
+ aflg = 0, /* -a - show status for all users */
+ Sflg = 0; /* -S - show password status */
+
+/*
+ * set to 1 if there are any flags which require root privileges,
+ * and require username to be specified
+ */
+static int anyflag = 0;
+
+#ifdef AGING
+static long age_min = 0; /* Minimum days before change */
+static long age_max = 0; /* Maximum days until change */
+#ifdef SHADOWPWD
+static long warn = 0; /* Warning days before change */
+static long inact = 0; /* Days without change before locked */
+#endif
+#endif
+
+static int do_update_age = 0;
+
+#ifndef USE_PAM
+static char crypt_passwd[128]; /* The "old-style" password, if present */
+static int do_update_pwd = 0;
+#endif
+
+#ifdef HAVE_TCFS
+static struct tcfspwd *tcfspword;
+static int tcfs_force = 0;
+#endif
+
+/*
+ * External identifiers
+ */
+
+#ifdef ATT_AGE
+extern char *l64a();
+#endif
+
+extern int optind; /* Index into argv[] for current option */
+extern char *optarg; /* Pointer to current option value */
+
+#ifndef HAVE_USERSEC_H
+#ifdef NDBM
+extern int sp_dbm_mode;
+extern int pw_dbm_mode;
+#endif
+#endif
+
+
+#define WRONGPWD2 "incorrect password for `%s'"
+#define CANTCHANGE2 "password locked for `%s'"
+
+#define TOOSOON2 "now < minimum age for `%s'"
+
+#define EXECFAILED2 "cannot execute %s"
+#define NOPERM2 "can't change pwd for `%s'"
+
+#define PWDBUSY2 "can't lock password file"
+#define OPNERROR2 "can't open password file"
+#define UPDERROR2 "error updating password entry"
+#define CLSERROR2 "can't rewrite password file"
+#define DBMERROR2 "error updaring dbm password entry"
+
+#ifdef HAVE_TCFS
+#define TCFSPWDBUSY2 "can't lock TCFS key database"
+#define TCFSOPNERROR2 "can't open TCFS key database"
+#define TCFSUPDERROR2 "error updating TCFS key database"
+#define TCFSCLSERROR2 "can't rewrite TCFS key database"
+#endif
+
+#define NOTROOT2 "can't setuid(0)"
+#define CHGPASSWD "password for `%s' changed by `%s'"
+#define NOCHGPASSWD "did not change password for `%s'"
+
+/* local function prototypes */
+static void usage(int);
+#ifndef USE_PAM
+#ifdef AUTH_METHODS
+static char *get_password(const char *);
+static int uses_default_method(const char *);
+#endif /* AUTH_METHODS */
+static int reuse(const char *, const struct passwd *);
+static int new_password(const struct passwd *);
+#ifdef SHADOWPWD
+static void check_password(const struct passwd *, const struct spwd *);
+#else /* !SHADOWPWD */
+static void check_password(const struct passwd *);
+#endif /* !SHADOWPWD */
+static char *insert_crypt_passwd(const char *, const char *);
+#endif /* !USE_PAM */
+static char *date_to_str(time_t);
+static const char *pw_status(const char *);
+static void print_status(const struct passwd *);
+static void fail_exit(int);
+static void oom(void);
+static char *update_crypt_pw(char *);
+static void update_noshadow(void);
+#ifdef SHADOWPWD
+static void update_shadow(void);
+#endif
+#ifdef HAVE_TCFS
+static void update_tcfs(void);
+#endif
+#ifdef HAVE_USERSEC_H
+static void update_userpw(char *);
+#endif
+static long getnumber(const char *);
+
+/*
+ * usage - print command usage and exit
+ */
+
+static void
+usage(int status)
+{
+ fprintf(stderr, _("usage: %s [ -f | -s ] [ name ]\n"), Prog);
+ if (amroot) {
+ fprintf(stderr,
+ _(" %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"),
+ Prog);
+ fprintf(stderr,
+ _(" %s { -l | -u | -d | -S | -e } name\n"),
+ Prog);
+ }
+ exit(status);
+}
+
+#ifndef USE_PAM
+#ifdef AUTH_METHODS
+/*
+ * get_password - locate encrypted password in authentication list
+ */
+
+static char *
+get_password(const char *list)
+{
+ char *cp, *end;
+ static char buf[257];
+
+ STRFCPY(buf, list);
+ for (cp = buf;cp;cp = end) {
+ if ((end = strchr (cp, ';')))
+ *end++ = 0;
+
+ if (cp[0] == '@')
+ continue;
+
+ return cp;
+ }
+ return (char *) 0;
+}
+
+/*
+ * uses_default_method - determine if "old-style" password present
+ *
+ * uses_default_method determines if a "old-style" password is present
+ * in the authentication string, and if one is present it extracts it.
+ */
+
+static int
+uses_default_method(const char *methods)
+{
+ char *cp;
+
+ if ((cp = get_password (methods))) {
+ STRFCPY(crypt_passwd, cp);
+ return 1;
+ }
+ return 0;
+}
+#endif /* AUTH_METHODS */
+
+static int
+reuse(const char *pass, const struct passwd *pw)
+{
+#ifdef HAVE_LIBCRACK_HIST
+ const char *reason;
+#ifdef HAVE_LIBCRACK_PW
+ const char *FascistHistoryPw(const char *,const struct passwd *);
+ reason = FascistHistory(pass, pw);
+#else
+ const char *FascistHistory(const char *, int);
+ reason = FascistHistory(pass, pw->pw_uid);
+#endif
+ if (reason) {
+ printf(_("Bad password: %s. "), reason);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * new_password - validate old password and replace with new
+ * (both old and new in global "char crypt_passwd[128]")
+ */
+
+/*ARGSUSED*/
+static int
+new_password(const struct passwd *pw)
+{
+ char *clear; /* Pointer to clear text */
+ char *cipher; /* Pointer to cipher text */
+ char *cp; /* Pointer to getpass() response */
+ char orig[200]; /* Original password */
+ char pass[200]; /* New password */
+ int i; /* Counter for retries */
+ int warned;
+ int pass_max_len;
+#ifdef HAVE_LIBCRACK_HIST
+ int HistUpdate(const char *, const char *);
+#endif
+
+ /*
+ * Authenticate the user. The user will be prompted for their
+ * own password.
+ */
+
+#ifdef HAVE_TCFS
+ tcfs_force = tcfs_force && amroot;
+
+ if ((tcfs_locate(name) && !tcfs_force) || (!amroot && crypt_passwd[0])) {
+ if (amroot) {
+ printf(_("User %s has a TCFS key, his old password is required.\n"), name);
+ printf(_("You can use -t option to force the change.\n"));
+ }
+#else
+ if (! amroot && crypt_passwd[0]) {
+#endif
+
+ if (!(clear = getpass(_("Old password: "))))
+ return -1;
+
+ cipher = pw_encrypt(clear, crypt_passwd);
+ if (strcmp(cipher, crypt_passwd) != 0) {
+ SYSLOG((LOG_WARN, WRONGPWD2, pw->pw_name));
+ sleep(1);
+ fprintf(stderr, _("Incorrect password for `%s'\n"),
+ pw->pw_name);
+ return -1;
+ }
+ STRFCPY(orig, clear);
+#ifdef HAVE_TCFS
+ STRFCPY(tcfspword->tcfsorig, clear);
+#endif
+ strzero(clear);
+ strzero(cipher);
+ } else {
+#ifdef HAVE_TCFS
+ if (tcfs_locate(name))
+ printf(_("Warning: user %s has a TCFS key.\n"), name);
+#endif
+ orig[0] = '\0';
+ }
+
+ /*
+ * Get the new password. The user is prompted for the new password
+ * and has five tries to get it right. The password will be tested
+ * for strength, unless it is the root user. This provides an escape
+ * for initial login passwords.
+ */
+
+ if (getdef_bool("MD5_CRYPT_ENAB"))
+ pass_max_len = 127;
+ else
+ pass_max_len = getdef_num("PASS_MAX_LEN", 8);
+
+ if (!qflg)
+ printf(_("\
+Enter the new password (minimum of %d, maximum of %d characters)\n\
+Please use a combination of upper and lower case letters and numbers.\n"),
+ getdef_num("PASS_MIN_LEN", 5), pass_max_len);
+
+ warned = 0;
+ for (i = getdef_num("PASS_CHANGE_TRIES", 5); i > 0; i--) {
+ if (!(cp = getpass(_("New password: ")))) {
+ memzero(orig, sizeof orig);
+ return -1;
+ }
+ if (warned && strcmp(pass, cp) != 0)
+ warned = 0;
+ STRFCPY(pass, cp);
+ strzero(cp);
+
+ if (!amroot && (!obscure(orig, pass, pw) || reuse(pass, pw))) {
+ printf(_("Try again.\n"));
+ continue;
+ }
+ /*
+ * If enabled, warn about weak passwords even if you are root
+ * (enter this password again to use it anyway). --marekm
+ */
+ if (amroot && !warned && getdef_bool("PASS_ALWAYS_WARN")
+ && (!obscure(orig, pass, pw) || reuse(pass, pw))) {
+ printf(_("\nWarning: weak password (enter it again to use it anyway).\n"));
+ warned++;
+ continue;
+ }
+ if (!(cp = getpass(_("Re-enter new password: ")))) {
+ memzero(orig, sizeof orig);
+ return -1;
+ }
+ if (strcmp (cp, pass))
+ fprintf(stderr, _("They don't match; try again.\n"));
+ else {
+ strzero(cp);
+ break;
+ }
+ }
+ memzero(orig, sizeof orig);
+
+ if (i == 0) {
+ memzero(pass, sizeof pass);
+ return -1;
+ }
+
+#ifdef HAVE_TCFS
+ STRFCPY(tcfspword->tcfspass, pass);
+#endif
+
+ /*
+ * Encrypt the password, then wipe the cleartext password.
+ */
+
+ cp = pw_encrypt(pass, crypt_make_salt());
+ memzero(pass, sizeof pass);
+
+#ifdef HAVE_LIBCRACK_HIST
+ HistUpdate(pw->pw_name, crypt_passwd);
+#endif
+ STRFCPY(crypt_passwd, cp);
+ return 0;
+}
+
+/*
+ * check_password - test a password to see if it can be changed
+ *
+ * check_password() sees if the invoker has permission to change the
+ * password for the given user.
+ */
+
+#ifdef SHADOWPWD
+static void
+check_password(const struct passwd *pw, const struct spwd *sp)
+{
+#else
+static void
+check_password(const struct passwd *pw)
+{
+#endif
+ time_t now, last, ok;
+ int exp_status;
+#ifdef HAVE_USERSEC_H
+ struct userpw *pu;
+#endif
+
+#ifdef SHADOWPWD
+ exp_status = isexpired(pw, sp);
+#else
+ exp_status = isexpired(pw);
+#endif
+
+ /*
+ * If not expired and the "change only if expired" option
+ * (idea from PAM) was specified, do nothing... --marekm
+ */
+ if (kflg && exp_status == 0)
+ exit(E_SUCCESS);
+
+ /*
+ * Root can change any password any time.
+ */
+
+ if (amroot)
+ return;
+
+ time(&now);
+
+#ifdef SHADOWPWD
+ /*
+ * Expired accounts cannot be changed ever. Passwords
+ * which are locked may not be changed. Passwords where
+ * min > max may not be changed. Passwords which have
+ * been inactive too long cannot be changed.
+ */
+
+ if (sp->sp_pwdp[0] == '!' || exp_status > 1 ||
+ (sp->sp_max >= 0 && sp->sp_min > sp->sp_max)) {
+ fprintf(stderr, _("The password for %s cannot be changed.\n"),
+ sp->sp_namp);
+ SYSLOG((LOG_WARN, CANTCHANGE2, sp->sp_namp));
+ closelog();
+ exit(E_NOPERM);
+ }
+
+ /*
+ * Passwords may only be changed after sp_min time is up.
+ */
+
+ last = sp->sp_lstchg * SCALE;
+ ok = last + (sp->sp_min > 0 ? sp->sp_min * SCALE : 0);
+
+#else /* !SHADOWPWD */
+ if (pw->pw_passwd[0] == '!' || exp_status > 1) {
+ fprintf(stderr, _("The password for %s cannot be changed.\n"),
+ pw->pw_name);
+ SYSLOG((LOG_WARN, CANTCHANGE2, pw->pw_name));
+ closelog();
+ exit(E_NOPERM);
+ }
+#ifdef ATT_AGE
+ /*
+ * Can always be changed if there is no age info
+ */
+
+ if (! pw->pw_age[0])
+ return;
+
+ last = a64l (pw->pw_age + 2) * WEEK;
+ ok = last + c64i (pw->pw_age[1]) * WEEK;
+#else /* !ATT_AGE */
+#ifdef HAVE_USERSEC_H
+ pu = getuserpw(pw->pw_name);
+ last = pu ? pu->upw_lastupdate : 0L;
+ ok = last + (minage > 0 ? minage * WEEK : 0);
+#else
+ last = 0;
+ ok = 0;
+#endif
+#endif /* !ATT_AGE */
+#endif /* !SHADOWPWD */
+ if (now < ok) {
+ fprintf(stderr, _("Sorry, the password for %s cannot be changed yet.\n"), pw->pw_name);
+ SYSLOG((LOG_WARN, TOOSOON2, pw->pw_name));
+ closelog();
+ exit(E_NOPERM);
+ }
+}
+
+/*
+ * insert_crypt_passwd - add an "old-style" password to authentication string
+ * result now malloced to avoid overflow, just in case. --marekm
+ */
+static char *
+insert_crypt_passwd(const char *string, const char *passwd)
+{
+#ifdef AUTH_METHODS
+ if (string && *string) {
+ char *cp, *result;
+
+ result = xmalloc(strlen(string) + strlen(passwd) + 1);
+ cp = result;
+ while (*string) {
+ if (string[0] == ';') {
+ *cp++ = *string++;
+ } else if (string[0] == '@') {
+ while (*string && *string != ';')
+ *cp++ = *string++;
+ } else {
+ while (*passwd)
+ *cp++ = *passwd++;
+
+ while (*string && *string != ';')
+ string++;
+ }
+ }
+ *cp = '\0';
+ return result;
+ }
+#endif
+ return xstrdup(passwd);
+}
+#endif /* !USE_PAM */
+
+static char *
+date_to_str(time_t t)
+{
+ static char buf[80];
+ struct tm *tm;
+
+ tm = gmtime(&t);
+#ifdef HAVE_STRFTIME
+ strftime(buf, sizeof buf, "%m/%d/%Y", tm);
+#else
+ snprintf(buf, sizeof buf, "%02d/%02d/%04d",
+ tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
+#endif
+ return buf;
+}
+
+static const char *
+pw_status(const char *pass)
+{
+ if (*pass == '*' || *pass == '!')
+ return "L";
+ if (*pass == '\0')
+ return "NP";
+ return "P";
+}
+
+/*
+ * print_status - print current password status
+ */
+
+static void
+print_status(const struct passwd *pw)
+{
+#ifdef SHADOWPWD
+ struct spwd *sp;
+#endif
+#ifdef HAVE_USERSEC_H
+ struct userpw *pu;
+#endif
+
+#ifdef SHADOWPWD
+ sp = getspnam(pw->pw_name);
+ if (sp) {
+ printf("%s %s %s %ld %ld %ld %ld\n",
+ pw->pw_name,
+ pw_status(sp->sp_pwdp),
+ date_to_str(sp->sp_lstchg * SCALE),
+ (sp->sp_min * SCALE) / DAY,
+ (sp->sp_max * SCALE) / DAY,
+ (sp->sp_warn * SCALE) / DAY,
+ (sp->sp_inact * SCALE) / DAY);
+ } else
+#endif
+ {
+#ifdef HAVE_USERSEC_H
+ pu = getuserpw(name);
+ printf("%s %s %s %d %d\n",
+ pw->pw_name,
+ pw_status(pw->pw_passwd),
+ date_to_str(pu ? pu->upw_lastupdate : 0L),
+ minage > 0 ? minage * 7 : 0,
+ maxage > 0 ? maxage * 7 : 10000);
+#else /* !HAVE_USERSEC_H */
+#ifdef ATT_AGE
+ printf("%s %s %s %d %d\n",
+ pw->pw_name,
+ pw_status(pw->pw_passwd),
+ date_to_str(strlen(pw->pw_age) > 2 ?
+ a64l(pw->pw_age + 2) * WEEK : 0L),
+ pw->pw_age[0] ? c64i(pw->pw_age[1]) * 7 : 0,
+ pw->pw_age[0] ? c64i(pw->pw_age[0]) * 7 : 10000);
+#else
+ printf("%s %s\n", pw->pw_name, pw_status(pw->pw_passwd));
+#endif
+#endif /* !HAVE_USERSEC_H */
+ }
+}
+
+
+static void
+fail_exit(int status)
+{
+ pw_unlock();
+#ifdef SHADOWPWD
+ spw_unlock();
+#endif
+#ifdef HAVE_TCFS
+ tcfs_unlock();
+#endif
+ exit(status);
+}
+
+static void
+oom(void)
+{
+ fprintf(stderr, _("%s: out of memory\n"), Prog);
+ fail_exit(E_FAILURE);
+}
+
+static char *
+update_crypt_pw(char *cp)
+{
+#ifndef USE_PAM
+ if (do_update_pwd)
+ cp = insert_crypt_passwd(cp, crypt_passwd);
+#endif
+
+ if (dflg)
+ cp = ""; /* XXX warning: const */
+
+ if (uflg && *cp == '!')
+ cp++;
+
+ if (lflg && *cp != '!') {
+ char *newpw = xmalloc(strlen(cp) + 2);
+
+ strcpy(newpw, "!");
+ strcat(newpw, cp);
+ cp = newpw;
+ }
+ return cp;
+}
+
+
+static void
+update_noshadow(void)
+{
+ const struct passwd *pw;
+ struct passwd *npw;
+#ifdef ATT_AGE
+ char age[5];
+ long week = time((time_t *) 0) / WEEK;
+ char *cp;
+#endif
+
+ if (!pw_lock()) {
+ fprintf(stderr,
+ _("Cannot lock the password file; try again later.\n"));
+ SYSLOG((LOG_WARN, PWDBUSY2));
+ exit(E_PWDBUSY);
+ }
+ if (!pw_open(O_RDWR)) {
+ fprintf(stderr, _("Cannot open the password file.\n"));
+ SYSLOG((LOG_ERR, OPNERROR2));
+ fail_exit(E_MISSING);
+ }
+ pw = pw_locate(name);
+ if (!pw) {
+ fprintf(stderr, _("%s: %s not found in /etc/passwd\n"),
+ Prog, name);
+ fail_exit(E_NOPERM);
+ }
+ npw = __pw_dup(pw);
+ if (!npw)
+ oom();
+ npw->pw_passwd = update_crypt_pw(npw->pw_passwd);
+#ifdef ATT_AGE
+ memzero(age, sizeof(age));
+ STRFCPY(age, npw->pw_age);
+
+ /*
+ * Just changing the password - update the last change date
+ * if there is one, otherwise the age just disappears.
+ */
+ if (do_update_age) {
+ if (strlen(age) > 2) {
+ cp = l64a(week);
+ age[2] = cp[0];
+ age[3] = cp[1];
+ } else {
+ age[0] = '\0';
+ }
+ }
+
+ if (xflg) {
+ if (age_max > 0)
+ age[0] = i64c((age_max + 6) / 7);
+ else
+ age[0] = '.';
+
+ if (age[1] == '\0')
+ age[1] = '.';
+ }
+ if (nflg) {
+ if (age[0] == '\0')
+ age[0] = 'z';
+
+ if (age_min > 0)
+ age[1] = i64c((age_min + 6) / 7);
+ else
+ age[1] = '.';
+ }
+ /*
+ * The last change date is added by -n or -x if it's
+ * not already there.
+ */
+ if ((nflg || xflg) && strlen(age) <= 2) {
+ cp = l64a(week);
+ age[2] = cp[0];
+ age[3] = cp[1];
+ }
+
+ /*
+ * Force password change - if last change date is
+ * present, it will be set to (today - max - 1 week).
+ * Otherwise, just set min = max = 0 (will disappear
+ * when password is changed).
+ */
+ if (eflg) {
+ if (strlen(age) > 2) {
+ cp = l64a(week - c64i(age[0]) - 1);
+ age[2] = cp[0];
+ age[3] = cp[1];
+ } else {
+ strcpy(age, "..");
+ }
+ }
+
+ npw->pw_age = age;
+#endif
+ if (!pw_update(npw)) {
+ fprintf(stderr, _("Error updating the password entry.\n"));
+ SYSLOG((LOG_ERR, UPDERROR2));
+ fail_exit(E_FAILURE);
+ }
+#ifdef NDBM
+ if (pw_dbm_present() && !pw_dbm_update(npw)) {
+ fprintf(stderr, _("Error updating the DBM password entry.\n"));
+ SYSLOG((LOG_ERR, DBMERROR2));
+ fail_exit(E_FAILURE);
+ }
+ endpwent();
+#endif
+ if (!pw_close()) {
+ fprintf(stderr, _("Cannot commit password file changes.\n"));
+ SYSLOG((LOG_ERR, CLSERROR2));
+ fail_exit(E_FAILURE);
+ }
+ pw_unlock();
+}
+
+#ifdef HAVE_TCFS
+static void
+update_tcfs(void)
+{
+ if (!tcfs_force) {
+ if (!tcfs_lock()) {
+ fprintf(stderr, _("Cannot lock the TCFS key database; try again later\n"));
+ SYSLOG((LOG_WARN, TCFSPWDBUSY2));
+ exit(E_PWDBUSY);
+ }
+ if (!tcfs_open(O_RDWR)) {
+ fprintf(stderr,
+ _("Cannot open the TCFS key database.\n"));
+ SYSLOG((LOG_WARN, TCFSOPNERROR2));
+ fail_exit(E_MISSING);
+ }
+ if (!tcfs_update(name, tcfspword)) {
+ fprintf(stderr,
+ _("Error updating the TCFS key database.\n"));
+ SYSLOG((LOG_ERR, TCFSUPDERROR2));
+ fail_exit(E_FAILURE);
+ }
+ if (!tcfs_close()) {
+ fprintf(stderr, _("Cannot commit TCFS changes.\n"));
+ SYSLOG((LOG_ERR, TCFSCLSERROR2));
+ fail_exit(E_FAILURE);
+ }
+ tcfs_unlock();
+ }
+}
+#endif /* HAVE_TCFS */
+
+#ifdef SHADOWPWD
+static void
+update_shadow(void)
+{
+ const struct spwd *sp;
+ struct spwd *nsp;
+
+ if (!spw_lock()) {
+ fprintf(stderr,
+ _("Cannot lock the password file; try again later.\n"));
+ SYSLOG((LOG_WARN, PWDBUSY2));
+ exit(E_PWDBUSY);
+ }
+ if (!spw_open(O_RDWR)) {
+ fprintf(stderr, _("Cannot open the password file.\n"));
+ SYSLOG((LOG_ERR, OPNERROR2));
+ fail_exit(E_FAILURE);
+ }
+ sp = spw_locate(name);
+ if (!sp) {
+ /* Try to update the password in /etc/passwd instead. */
+ spw_close();
+ update_noshadow();
+ spw_unlock();
+ return;
+ }
+ nsp = __spw_dup(sp);
+ if (!nsp)
+ oom();
+ nsp->sp_pwdp = update_crypt_pw(nsp->sp_pwdp);
+ if (xflg)
+ nsp->sp_max = (age_max * DAY) / SCALE;
+ if (nflg)
+ nsp->sp_min = (age_min * DAY) / SCALE;
+ if (wflg)
+ nsp->sp_warn = (warn * DAY) / SCALE;
+ if (iflg)
+ nsp->sp_inact = (inact * DAY) / SCALE;
+ if (do_update_age)
+ nsp->sp_lstchg = time((time_t *) 0) / SCALE;
+ /*
+ * Force change on next login, like SunOS 4.x passwd -e or
+ * Solaris 2.x passwd -f. Solaris 2.x seems to do the same
+ * thing (set sp_lstchg to 0).
+ */
+ if (eflg)
+ nsp->sp_lstchg = 0;
+
+ if (!spw_update(nsp)) {
+ fprintf(stderr, _("Error updating the password entry.\n"));
+ SYSLOG((LOG_ERR, UPDERROR2));
+ fail_exit(E_FAILURE);
+ }
+#ifdef NDBM
+ if (sp_dbm_present() && !sp_dbm_update(nsp)) {
+ fprintf(stderr, _("Error updating the DBM password entry.\n"));
+ SYSLOG((LOG_ERR, DBMERROR2));
+ fail_exit(E_FAILURE);
+ }
+ endspent();
+#endif
+ if (!spw_close()) {
+ fprintf(stderr, _("Cannot commit password file changes.\n"));
+ SYSLOG((LOG_ERR, CLSERROR2));
+ fail_exit(E_FAILURE);
+ }
+ spw_unlock();
+}
+#endif /* SHADOWPWD */
+
+#ifdef HAVE_USERSEC_H
+static void
+update_userpw(char *cp)
+{
+ struct userpw userpw;
+
+ /*
+ * AIX very conveniently has its own mechanism for updating
+ * passwords. Use it instead ...
+ */
+
+ strcpy(userpw.upw_name, name);
+ userpw.upw_passwd = update_crypt_pw(cp);
+ userpw.upw_lastupdate = time (0);
+ userpw.upw_flags = 0;
+
+ setpwdb(S_WRITE);
+
+ if (putuserpw(&userpw)) {
+ fprintf(stderr, _("Error updating the password entry.\n"));
+ SYSLOG((LOG_ERR, UPDERROR2));
+ closelog();
+ exit(E_FAILURE);
+ }
+ endpwdb();
+}
+#endif
+
+static long
+getnumber(const char *str)
+{
+ long val;
+ char *cp;
+
+ val = strtol(str, &cp, 10);
+ if (*cp)
+ usage(E_BAD_ARG);
+ return val;
+}
+
+/*
+ * passwd - change a user's password file information
+ *
+ * This command controls the password file and commands which are
+ * used to modify it.
+ *
+ * The valid options are
+ *
+ * -l lock the named account (*)
+ * -u unlock the named account (*)
+ * -d delete the password for the named account (*)
+ * -e expire the password for the named account (*)
+ * -x # set sp_max to # days (*)
+ * -n # set sp_min to # days (*)
+ * -w # set sp_warn to # days (*)
+ * -i # set sp_inact to # days (*)
+ * -S show password status of named account
+ * -g execute gpasswd command to interpret flags
+ * -f execute chfn command to interpret flags
+ * -s execute chsh command to interpret flags
+ * -k change password only if expired
+ * -t force 'passwd' to change the password regardless of TCFS
+ *
+ * (*) requires root permission to execute.
+ *
+ * All of the time fields are entered in days and converted to the
+ * appropriate internal format. For finer resolute the chage
+ * command must be used.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int flag; /* Current option to process */
+ const struct passwd *pw; /* Password file entry for user */
+#ifndef USE_PAM
+ char *cp; /* Miscellaneous character pointing */
+#ifdef SHADOWPWD
+ const struct spwd *sp; /* Shadow file entry for user */
+#endif
+#endif
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /*
+ * The program behaves differently when executed by root
+ * than when executed by a normal user.
+ */
+ amroot = (getuid () == 0);
+
+ /*
+ * Get the program name. The program name is used as a
+ * prefix to most error messages.
+ */
+ Prog = Basename(argv[0]);
+
+ sanitize_env();
+
+ OPENLOG("passwd");
+
+ /*
+ * Start with the flags which cause another command to be
+ * executed. The effective UID will be set back to the
+ * real UID and the new command executed with the flags
+ *
+ * These flags are deprecated, may change in a future
+ * release. Please run these programs directly. --marekm
+ */
+
+ if (argc > 1 && argv[1][0] == '-' && strchr ("gfs", argv[1][1])) {
+ char buf[200];
+
+ setuid(getuid());
+ switch (argv[1][1]) {
+ case 'g':
+ argv[1] = GPASSWD_PROGRAM; /* XXX warning: const */
+ break;
+ case 'f':
+ argv[1] = CHFN_PROGRAM; /* XXX warning: const */
+ break;
+ case 's':
+ argv[1] = CHSH_PROGRAM; /* XXX warning: const */
+ break;
+ default:
+ usage(E_BAD_ARG);
+ }
+ snprintf(buf, sizeof buf, _("%s: Cannot execute %s"),
+ Prog, argv[1]);
+ execvp(argv[1], &argv[1]);
+ perror(buf);
+ SYSLOG((LOG_ERR, EXECFAILED2, argv[1]));
+ closelog();
+ exit(E_FAILURE);
+ }
+
+ /*
+ * The remaining arguments will be processed one by one and
+ * executed by this command. The name is the last argument
+ * if it does not begin with a "-", otherwise the name is
+ * determined from the environment and must agree with the
+ * real UID. Also, the UID will be checked for any commands
+ * which are restricted to root only.
+ */
+
+#ifdef SHADOWPWD
+#define FLAGS "adlqr:uSekn:x:i:w:"
+#ifdef HAVE_TCFS
+#undef FLAGS
+#define FLAGS "adlqr:uSekn:x:i:w:t"
+#endif
+#else
+#ifdef AGING
+#define FLAGS "adlqr:uSekn:x:"
+#ifdef HAVE_TCFS
+#undef FLAGS
+#define FLAGS "adlqr:uSekn:x:t"
+#endif
+#else
+#define FLAGS "adlqr:uS"
+#ifdef HAVE_TCFS
+#undef FLAGS
+#define FLAGS "adlqr:uSt"
+#endif
+#endif
+#endif
+ while ((flag = getopt(argc, argv, FLAGS)) != EOF) {
+#undef FLAGS
+ switch (flag) {
+#ifdef AGING
+ case 'x':
+ age_max = getnumber(optarg);
+ xflg++;
+ anyflag = 1;
+ break;
+ case 'n':
+ age_min = getnumber(optarg);
+ nflg++;
+ anyflag = 1;
+ break;
+#ifdef HAVE_TCFS
+ case 't':
+ tcfs_force = 1;
+ break;
+#endif
+#ifdef SHADOWPWD
+ case 'w':
+ warn = getnumber(optarg);
+ if (warn >= -1)
+ wflg++;
+ anyflag = 1;
+ break;
+ case 'i':
+ inact = getnumber(optarg);
+ if (inact >= -1)
+ iflg++;
+ anyflag = 1;
+ break;
+#endif /* SHADOWPWD */
+ case 'e':
+ eflg++;
+ anyflag = 1;
+ break;
+ case 'k':
+ /* change only if expired, like Linux-PAM passwd -k. */
+ kflg++; /* ok for users */
+ break;
+#endif /* AGING */
+ case 'a':
+ aflg++;
+ break;
+ case 'q':
+ qflg++; /* ok for users */
+ break;
+ case 'S':
+ Sflg++; /* ok for users */
+ break;
+ case 'd':
+ dflg++;
+ anyflag = 1;
+ break;
+ case 'l':
+ lflg++;
+ anyflag = 1;
+ break;
+ case 'u':
+ uflg++;
+ anyflag = 1;
+ break;
+ case 'r':
+ /* -r repository (files|nis|nisplus) */
+ /* only "files" supported for now */
+ if (strcmp(optarg, "files") != 0) {
+ fprintf(stderr,
+ _("%s: repository %s not supported\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ break;
+ default:
+ usage(E_BAD_ARG);
+ }
+ }
+
+#ifdef HAVE_USERSEC_H
+ /*
+ * The aging information lives someplace else. Get it from the
+ * login.cfg file
+ */
+
+ if (getconfattr(SC_SYS_PASSWD, SC_MINAGE, &minage, SEC_INT))
+ minage = -1;
+
+ if (getconfattr(SC_SYS_PASSWD, SC_MAXAGE, &maxage, SEC_INT))
+ maxage = -1;
+#endif /* HAVE_USERSEC_H */
+
+ /*
+ * Now I have to get the user name. The name will be gotten
+ * from the command line if possible. Otherwise it is figured
+ * out from the environment.
+ */
+
+ pw = get_my_pwent();
+ if (!pw) {
+ fprintf(stderr, _("%s: Cannot determine your user name.\n"),
+ Prog);
+ exit(E_NOPERM);
+ }
+ myname = xstrdup(pw->pw_name);
+ if (optind < argc)
+ name = argv[optind];
+ else
+ name = myname;
+
+ /*
+ * The -a flag requires -S, no other flags, no username, and
+ * you must be root. --marekm
+ */
+
+ if (aflg) {
+ if (anyflag || !Sflg || (optind < argc))
+ usage(E_USAGE);
+ if (!amroot) {
+ fprintf(stderr, _("%s: Permission denied.\n"), Prog);
+ exit(E_NOPERM);
+ }
+ setpwent();
+ while ((pw = getpwent()))
+ print_status(pw);
+ exit(E_SUCCESS);
+ }
+
+#if 0
+ /*
+ * Allow certain users (administrators) to change passwords of
+ * certain users. Not implemented yet... --marekm
+ */
+ if (may_change_passwd(myname, name))
+ amroot = 1;
+#endif
+
+ /*
+ * If any of the flags were given, a user name must be supplied
+ * on the command line. Only an unadorned command line doesn't
+ * require the user's name be given. Also, -x, -n, -w, -i, -e, -d,
+ * -l, -u may appear with each other. -S, -k must appear alone.
+ */
+
+ /*
+ * -S now ok for normal users (check status of my own account),
+ * and doesn't require username. --marekm
+ */
+
+ if (anyflag && optind >= argc)
+ usage(E_USAGE);
+
+ if (anyflag + Sflg + kflg > 1)
+ usage(E_USAGE);
+
+ if (anyflag && !amroot) {
+ fprintf(stderr, _("%s: Permission denied\n"), Prog);
+ exit(E_NOPERM);
+ }
+
+#ifdef NDBM
+ endpwent();
+ pw_dbm_mode = O_RDWR;
+#ifdef SHADOWPWD
+ sp_dbm_mode = O_RDWR;
+#endif
+#endif
+
+ pw = getpwnam(name);
+ if (!pw) {
+ fprintf(stderr, _("%s: Unknown user %s\n"), Prog, name);
+ exit(E_NOPERM);
+ }
+
+ /*
+ * Now I have a name, let's see if the UID for the name
+ * matches the current real UID.
+ */
+
+ if (!amroot && pw->pw_uid != getuid ()) {
+ fprintf(stderr, _("You may not change the password for %s.\n"),
+ name);
+ SYSLOG((LOG_WARN, NOPERM2, name));
+ closelog();
+ exit(E_NOPERM);
+ }
+
+ if (Sflg) {
+ print_status(pw);
+ exit(E_SUCCESS);
+ }
+
+#ifndef USE_PAM
+#ifdef SHADOWPWD
+ /*
+ * The user name is valid, so let's get the shadow file
+ * entry.
+ */
+
+ sp = getspnam(name);
+ if (!sp)
+ sp = pwd_to_spwd(pw);
+
+ cp = sp->sp_pwdp;
+#else
+ cp = pw->pw_passwd;
+#endif
+
+ /*
+ * If there are no other flags, just change the password.
+ */
+
+ if (!anyflag) {
+#ifdef AUTH_METHODS
+ if (strchr(cp, '@')) {
+ if (pw_auth(cp, name, PW_CHANGE, (char *)0)) {
+ SYSLOG((LOG_INFO, NOCHGPASSWD, name));
+ closelog();
+ exit(E_NOPERM);
+ } else if (! uses_default_method(cp)) {
+ do_update_age = 1;
+ goto done;
+ }
+ } else
+#endif
+ STRFCPY(crypt_passwd, cp);
+
+ /*
+ * See if the user is permitted to change the password.
+ * Otherwise, go ahead and set a new password.
+ */
+
+#ifdef SHADOWPWD
+ check_password(pw, sp);
+#else
+ check_password(pw);
+#endif
+
+#ifdef HAVE_TCFS
+ tcfspword = (struct tcfspwd *)calloc(1, sizeof (struct tcfspwd));
+#endif
+ /*
+ * Let the user know whose password is being changed.
+ */
+ if (!qflg)
+ printf(_("Changing password for %s\n"), name);
+
+ if (new_password(pw)) {
+ fprintf(stderr,
+ _("The password for %s is unchanged.\n"),
+ name);
+ closelog();
+ exit(E_NOPERM);
+ }
+ do_update_pwd = 1;
+ do_update_age = 1;
+ }
+
+#ifdef AUTH_METHODS
+done:
+#endif
+#endif /* !USE_PAM */
+ /*
+ * Before going any further, raise the ulimit to prevent
+ * colliding into a lowered ulimit, and set the real UID
+ * to root to protect against unexpected signals. Any
+ * keyboard signals are set to be ignored.
+ */
+
+ pwd_init();
+
+ /*
+ * Don't set the real UID for PAM...
+ */
+#ifdef USE_PAM
+ if (!anyflag) {
+ do_pam_passwd(name, qflg, kflg);
+ exit(E_SUCCESS);
+ }
+#endif /* USE_PAM */
+ if (setuid(0)) {
+ fprintf(stderr, _("Cannot change ID to root.\n"));
+ SYSLOG((LOG_ERR, NOTROOT2));
+ closelog();
+ exit(E_NOPERM);
+ }
+#ifdef HAVE_USERSEC_H
+ update_userpw(pw->pw_passwd);
+#else /* !HAVE_USERSEC_H */
+
+#ifdef SHADOWPWD
+ if (spw_file_present())
+ update_shadow();
+ else
+#endif
+ update_noshadow();
+
+#ifdef HAVE_TCFS
+ if (tcfs_locate(name) && tcfs_file_present())
+ update_tcfs();
+#endif
+#endif /* !HAVE_USERSEC_H */
+ SYSLOG((LOG_INFO, CHGPASSWD, name, myname));
+ closelog();
+ if (!qflg)
+ printf(_("Password changed.\n"));
+ exit(E_SUCCESS);
+ /*NOTREACHED*/
+}
diff --git a/current/src/patchlevel.h b/current/src/patchlevel.h
new file mode 100644
index 00000000..3fb8dce4
--- /dev/null
+++ b/current/src/patchlevel.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1991 - 1995, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Revision History
+ * 11/25/91 3.1.1 patchlevel 14
+ * Added "login.defs" to Makefile
+ * 12/02/91 3.1.2 patchlevel 15
+ * Bugs found by users
+ * 12/28/91 3.1.3 patchlevel 16
+ * Changes for SunOS 4.1.1
+ * 02/08/92 3.1.4 patchlevel 17
+ * Changes for SVR4, plus bug fixes
+ * 04/03/92 3.2.1 patchlevel 18
+ * Minor bug fixes, new baseline
+ * 07/07/92 3.2.2 patchlevel 20
+ * Added administrator defined authentication
+ * 11/04/92 3.2.3 patchlevel 21
+ * Bug fixes for SVR4
+ * 07/23/93 3.3.0 patchlevel 23
+ * New baseline release
+ * 08/23/93 3.3.1 patchlevel 24
+ * Bug fixes for SunOS 4.1.1
+ * 08/27/93 3.3.2 patchlevel 25
+ * Initial NIS support changes
+ * 12/03/95 3.3.3 patchlevel 26
+ * This is the Linux beta baseline. Marek will
+ * change the name some other day. -- jfh
+ * $Id: patchlevel.h,v 1.2 1997/05/01 23:07:16 marekm Exp $
+ */
+
+#define RELEASE 3
+#define PATCHLEVEL 26
+#define VERSION "3.3.3"
diff --git a/current/src/pwck.c b/current/src/pwck.c
new file mode 100644
index 00000000..00551794
--- /dev/null
+++ b/current/src/pwck.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright 1992 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: pwck.c,v 1.15 2000/09/02 18:40:44 marekm Exp $")
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <grp.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include "chkname.h"
+#include <pwd.h>
+
+#include "commonio.h"
+
+#include "pwio.h"
+extern void __pw_del_entry(const struct commonio_entry *);
+extern struct commonio_entry *__pw_get_head(void);
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+extern void __spw_del_entry(const struct commonio_entry *);
+extern struct commonio_entry *__spw_get_head(void);
+#endif
+
+/*
+ * Exit codes
+ */
+
+#define E_OKAY 0
+#define E_USAGE 1
+#define E_BADENTRY 2
+#define E_CANTOPEN 3
+#define E_CANTLOCK 4
+#define E_CANTUPDATE 5
+
+/*
+ * Global variables
+ */
+
+extern int optind;
+extern char *optarg;
+
+/*
+ * Local variables
+ */
+
+static char *Prog;
+static const char *pwd_file = PASSWD_FILE;
+#ifdef SHADOWPWD
+static const char *spw_file = SHADOW_FILE;
+#endif
+static int read_only = 0;
+static int quiet = 0; /* don't report warnings, only errors */
+
+/* local function prototypes */
+static void usage(void);
+static int yes_or_no(void);
+
+/*
+ * usage - print syntax message and exit
+ */
+
+static void
+usage(void)
+{
+#ifdef SHADOWPWD
+ fprintf(stderr, _("Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"), Prog);
+#else
+ fprintf(stderr, _("Usage: %s [ -qr ] [ passwd ]\n"), Prog);
+#endif
+ exit(E_USAGE);
+}
+
+/*
+ * yes_or_no - get answer to question from the user
+ */
+
+static int
+yes_or_no(void)
+{
+ char buf[80];
+
+ /*
+ * In read-only mode all questions are answered "no".
+ */
+
+ if (read_only) {
+ puts(_("No"));
+ return 0;
+ }
+
+ /*
+ * Get a line and see what the first character is.
+ */
+
+ if (fgets(buf, sizeof buf, stdin))
+ return buf[0] == 'y' || buf[0] == 'Y';
+
+ return 0;
+}
+
+/*
+ * pwck - verify password file integrity
+ */
+
+int
+main(int argc, char **argv)
+{
+ int arg;
+ int errors = 0;
+ int deleted = 0;
+ struct commonio_entry *pfe, *tpfe;
+ struct passwd *pwd;
+#ifdef SHADOWPWD
+ struct commonio_entry *spe, *tspe;
+ struct spwd *spw;
+ int is_shadow = 0;
+#endif
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+ /*
+ * Parse the command line arguments
+ */
+
+ while ((arg = getopt(argc, argv, "eqr")) != EOF) {
+ switch (arg) {
+ case 'e': /* added for Debian shadow-961025-2 compatibility */
+ case 'q':
+ quiet = 1;
+ break;
+ case 'r':
+ read_only = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ /*
+ * Make certain we have the right number of arguments
+ */
+
+#ifdef SHADOWPWD
+ if (optind != argc && optind + 1 != argc && optind + 2 != argc)
+#else
+ if (optind != argc && optind + 1 != argc)
+#endif
+ usage();
+
+ /*
+ * If there are two left over filenames, use those as the
+ * password and shadow password filenames.
+ */
+
+ if (optind != argc) {
+ pwd_file = argv[optind];
+ pw_name(pwd_file);
+ }
+#ifdef SHADOWPWD
+ if (optind + 2 == argc) {
+ spw_file = argv[optind + 1];
+ spw_name(spw_file);
+ is_shadow = 1;
+ } else if (optind == argc)
+ is_shadow = spw_file_present();
+#endif
+
+ /*
+ * Lock the files if we aren't in "read-only" mode
+ */
+
+ if (!read_only) {
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: cannot lock file %s\n"),
+ Prog, pwd_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN,"cannot lock %s\n",pwd_file));
+ closelog();
+ exit(E_CANTLOCK);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow && !spw_lock()) {
+ fprintf(stderr, _("%s: cannot lock file %s\n"),
+ Prog, spw_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN,"cannot lock %s\n",spw_file));
+ closelog();
+ exit(E_CANTLOCK);
+ }
+#endif
+ }
+
+ /*
+ * Open the files. Use O_RDONLY if we are in read_only mode,
+ * O_RDWR otherwise.
+ */
+
+ if (!pw_open(read_only ? O_RDONLY:O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open file %s\n"),
+ Prog, pwd_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN, "cannot open %s\n", pwd_file));
+ closelog();
+ exit(E_CANTOPEN);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow && !spw_open(read_only ? O_RDONLY : O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open file %s\n"),
+ Prog, spw_file);
+ if (optind == argc)
+ SYSLOG((LOG_WARN, "cannot open %s\n", spw_file));
+ closelog();
+ exit(E_CANTOPEN);
+ }
+#endif
+
+ /*
+ * Loop through the entire password file.
+ */
+
+ for (pfe = __pw_get_head(); pfe; pfe = pfe->next) {
+ /*
+ * If this is a NIS line, skip it. You can't "know" what
+ * NIS is going to do without directly asking NIS ...
+ */
+
+ if (pfe->line[0] == '+' || pfe->line[0] == '-')
+ continue;
+
+ /*
+ * Start with the entries that are completely corrupt.
+ * They have no (struct passwd) entry because they couldn't
+ * be parsed properly.
+ */
+
+ if (!pfe->eptr) {
+
+ /*
+ * Tell the user this entire line is bogus and
+ * ask them to delete it.
+ */
+
+ printf(_("invalid password file entry\n"));
+ printf(_("delete line `%s'? "), pfe->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (!yes_or_no())
+ continue;
+
+ /*
+ * All password file deletions wind up here. This
+ * code removes the current entry from the linked
+ * list. When done, it skips back to the top of
+ * the loop to try out the next list element.
+ */
+
+delete_pw:
+ SYSLOG((LOG_INFO, "delete passwd line `%s'\n",
+ pfe->line));
+ deleted++;
+
+ __pw_del_entry(pfe);
+ continue;
+ }
+
+ /*
+ * Password structure is good, start using it.
+ */
+
+ pwd = pfe->eptr;
+
+ /*
+ * Make sure this entry has a unique name.
+ */
+
+ for (tpfe = __pw_get_head(); tpfe; tpfe = tpfe->next) {
+ const struct passwd *ent = tpfe->eptr;
+
+ /*
+ * Don't check this entry
+ */
+
+ if (tpfe == pfe)
+ continue;
+
+ /*
+ * Don't check invalid entries.
+ */
+
+ if (!ent)
+ continue;
+
+ if (strcmp(pwd->pw_name, ent->pw_name) != 0)
+ continue;
+
+ /*
+ * Tell the user this entry is a duplicate of
+ * another and ask them to delete it.
+ */
+
+ puts(_("duplicate password entry\n"));
+ printf(_("delete line `%s'? "), pfe->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (yes_or_no())
+ goto delete_pw;
+ }
+
+ /*
+ * Check for invalid usernames. --marekm
+ */
+ if (!check_user_name(pwd->pw_name)) {
+ printf(_("invalid user name `%s'\n"), pwd->pw_name);
+ errors++;
+ }
+
+ /*
+ * Check for a Slackware bug. Make sure UID is not -1
+ * (it has special meaning for some syscalls). --marekm
+ */
+
+ if (pwd->pw_uid == (uid_t) -1) {
+ printf(_("user %s: bad UID (%d)\n"),
+ pwd->pw_name, (int) pwd->pw_uid);
+ errors++;
+ }
+
+ /*
+ * Make sure the primary group exists
+ */
+
+ if (!quiet && !getgrgid(pwd->pw_gid)) {
+
+ /*
+ * No primary group, just give a warning
+ */
+
+ printf(_("user %s: no group %d\n"),
+ pwd->pw_name, (int) pwd->pw_gid);
+ errors++;
+ }
+
+ /*
+ * Make sure the home directory exists
+ */
+
+ if (!quiet && access(pwd->pw_dir, F_OK)) {
+
+ /*
+ * Home directory doesn't exist, give a warning
+ */
+
+ printf(_("user %s: directory %s does not exist\n"),
+ pwd->pw_name, pwd->pw_dir);
+ errors++;
+ }
+
+ /*
+ * Make sure the login shell is executable
+ */
+
+ if (!quiet && pwd->pw_shell[0] && access(pwd->pw_shell, F_OK)) {
+
+ /*
+ * Login shell doesn't exist, give a warning
+ */
+
+ printf(_("user %s: program %s does not exist\n"),
+ pwd->pw_name, pwd->pw_shell);
+ errors++;
+ }
+ }
+
+#ifdef SHADOWPWD
+ if (!is_shadow)
+ goto shadow_done;
+
+ /*
+ * Loop through the entire shadow password file.
+ */
+
+ for (spe = __spw_get_head(); spe; spe = spe->next) {
+ /*
+ * If this is a NIS line, skip it. You can't "know" what
+ * NIS is going to do without directly asking NIS ...
+ */
+
+ if (spe->line[0] == '+' || spe->line[0] == '-')
+ continue;
+
+ /*
+ * Start with the entries that are completely corrupt.
+ * They have no (struct spwd) entry because they couldn't
+ * be parsed properly.
+ */
+
+ if (!spe->eptr) {
+
+ /*
+ * Tell the user this entire line is bogus and
+ * ask them to delete it.
+ */
+
+ printf(_("invalid shadow password file entry\n"));
+ printf(_("delete line `%s'? "), spe->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (!yes_or_no())
+ continue;
+
+ /*
+ * All shadow file deletions wind up here. This
+ * code removes the current entry from the linked
+ * list. When done, it skips back to the top of
+ * the loop to try out the next list element.
+ */
+
+delete_spw:
+ SYSLOG((LOG_INFO, "delete shadow line `%s'\n",
+ spe->line));
+ deleted++;
+
+ __spw_del_entry(spe);
+ continue;
+ }
+
+ /*
+ * Shadow password structure is good, start using it.
+ */
+
+ spw = spe->eptr;
+
+ /*
+ * Make sure this entry has a unique name.
+ */
+
+ for (tspe = __spw_get_head(); tspe; tspe = tspe->next) {
+ const struct spwd *ent = tspe->eptr;
+
+ /*
+ * Don't check this entry
+ */
+
+ if (tspe == spe)
+ continue;
+
+ /*
+ * Don't check invalid entries.
+ */
+
+ if (!ent)
+ continue;
+
+ if (strcmp(spw->sp_namp, ent->sp_namp) != 0)
+ continue;
+
+ /*
+ * Tell the user this entry is a duplicate of
+ * another and ask them to delete it.
+ */
+
+ puts(_("duplicate shadow password entry\n"));
+ printf(_("delete line `%s'? "), spe->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (yes_or_no())
+ goto delete_spw;
+ }
+
+ /*
+ * Make sure this entry exists in the /etc/passwd
+ * file.
+ */
+
+ if (!pw_locate(spw->sp_namp)) {
+
+ /*
+ * Tell the user this entry has no matching
+ * /etc/passwd entry and ask them to delete it.
+ */
+
+ puts(_("no matching password file entry\n"));
+ printf(_("delete line `%s'? "), spe->line);
+ errors++;
+
+ /*
+ * prompt the user to delete the entry or not
+ */
+
+ if (yes_or_no())
+ goto delete_spw;
+ }
+
+ /*
+ * Warn if last password change in the future. --marekm
+ */
+
+ if (!quiet && spw->sp_lstchg > time((time_t *)0) / SCALE) {
+ printf(_("user %s: last password change in the future\n"), spw->sp_namp);
+ errors++;
+ }
+ }
+
+shadow_done:
+#endif
+
+ /*
+ * All done. If there were no deletions we can just abandon any
+ * changes to the files.
+ */
+
+ if (deleted) {
+ if (!pw_close()) {
+ fprintf(stderr, _("%s: cannot update file %s\n"),
+ Prog, pwd_file);
+ SYSLOG((LOG_WARN, "cannot update %s\n", pwd_file));
+ closelog();
+ exit(E_CANTUPDATE);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow && !spw_close()) {
+ fprintf(stderr, _("%s: cannot update file %s\n"),
+ Prog, spw_file);
+ SYSLOG((LOG_WARN, "cannot update %s\n", spw_file));
+ closelog();
+ exit(E_CANTUPDATE);
+ }
+#endif
+ }
+
+ /*
+ * Don't be anti-social - unlock the files when you're done.
+ */
+
+#ifdef SHADOWPWD
+ if (is_shadow)
+ spw_unlock();
+#endif
+ (void) pw_unlock();
+
+ /*
+ * Tell the user what we did and exit.
+ */
+
+ if (errors)
+#ifdef NDBM
+ printf(deleted ?
+ _("%s: the files have been updated; run mkpasswd\n") :
+ _("%s: no changes\n"), Prog);
+#else
+ printf(deleted ?
+ _("%s: the files have been updated\n") :
+ _("%s: no changes\n"), Prog);
+#endif
+
+ closelog();
+ exit(errors ? E_BADENTRY : E_OKAY);
+}
diff --git a/current/src/pwconv.c b/current/src/pwconv.c
new file mode 100644
index 00000000..3a32370b
--- /dev/null
+++ b/current/src/pwconv.c
@@ -0,0 +1,187 @@
+/*
+ * pwconv - create or update /etc/shadow with information from
+ * /etc/passwd.
+ *
+ * It is more like SysV pwconv, slightly different from the
+ * original Shadow pwconv. Depends on "x" as password in
+ * /etc/passwd which means that the password has already been
+ * moved to /etc/shadow. There is no need to move /etc/npasswd
+ * to /etc/passwd, password files are updated using library
+ * routines with proper locking.
+ *
+ * Can be used to update /etc/shadow after adding/deleting users
+ * by editing /etc/passwd. There is no man page yet, but this
+ * program should be close to pwconv(1M) on Solaris 2.x.
+ *
+ * Warning: make sure that all users have "x" as the password in
+ * /etc/passwd before running this program for the first time on
+ * a system which already has shadow passwords. Anything else
+ * (like "*" from old versions of the shadow suite) will replace
+ * the user's encrypted password in /etc/shadow.
+ *
+ * Doesn't currently support pw_age information in /etc/passwd,
+ * and doesn't support DBM files. Add it if you need it...
+ *
+ * Copyright (C) 1996-1997, Marek Michalkiewicz
+ * <marekm@i17linuxb.ists.pwr.wroc.pl>
+ * This program may be freely used and distributed for any purposes.
+ * If you improve it, please send me your changes. Thanks!
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: pwconv.c,v 1.11 2000/08/26 18:27:18 marekm Exp $")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <pwd.h>
+#include "prototypes.h"
+#include "defines.h"
+#include "pwio.h"
+#include "shadowio.h"
+#include "getdef.h"
+
+/*
+ * exit status values
+ */
+
+#define E_SUCCESS 0 /* success */
+#define E_NOPERM 1 /* permission denied */
+#define E_USAGE 2 /* bad command syntax */
+#define E_FAILURE 3 /* unexpected failure, nothing done */
+#define E_MISSING 4 /* unexpected failure, passwd file missing */
+#define E_PWDBUSY 5 /* passwd file(s) busy */
+#define E_BADENTRY 6 /* bad shadow entry */
+
+static int
+ shadow_locked = 0,
+ passwd_locked = 0;
+
+/* local function prototypes */
+static void fail_exit(int);
+
+static void
+fail_exit(int status)
+{
+ if (shadow_locked)
+ spw_unlock();
+ if (passwd_locked)
+ pw_unlock();
+ exit(status);
+}
+
+int
+main(int argc, char **argv)
+{
+ const struct passwd *pw;
+ struct passwd pwent;
+ const struct spwd *sp;
+ struct spwd spent;
+ char *Prog = argv[0];
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: can't lock passwd file\n"), Prog);
+ fail_exit(E_PWDBUSY);
+ }
+ passwd_locked++;
+ if (!pw_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open passwd file\n"), Prog);
+ fail_exit(E_MISSING);
+ }
+
+ if (!spw_lock()) {
+ fprintf(stderr, _("%s: can't lock shadow file\n"), Prog);
+ fail_exit(E_PWDBUSY);
+ }
+ shadow_locked++;
+ if (!spw_open(O_CREAT | O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow file\n"), Prog);
+ fail_exit(E_FAILURE);
+ }
+
+ /*
+ * Remove /etc/shadow entries for users not in /etc/passwd.
+ */
+ spw_rewind();
+ while ((sp = spw_next())) {
+ if (pw_locate(sp->sp_namp))
+ continue;
+
+ if (!spw_remove(sp->sp_namp)) {
+ /*
+ * This shouldn't happen (the entry exists) but...
+ */
+ fprintf(stderr,
+ _("%s: can't remove shadow entry for %s\n"),
+ Prog, sp->sp_namp);
+ fail_exit(E_FAILURE);
+ }
+ }
+
+ /*
+ * Update shadow entries which don't have "x" as pw_passwd.
+ * Add any missing shadow entries.
+ */
+ pw_rewind();
+ while ((pw = pw_next())) {
+ sp = spw_locate(pw->pw_name);
+ if (sp) {
+ /* do we need to update this entry? */
+ if (strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)
+ continue;
+ /* update existing shadow entry */
+ spent = *sp;
+ } else {
+ /* add new shadow entry */
+ memset(&spent, 0, sizeof spent);
+ spent.sp_namp = pw->pw_name;
+ spent.sp_min = getdef_num("PASS_MIN_DAYS", -1);
+ spent.sp_max = getdef_num("PASS_MAX_DAYS", -1);
+ spent.sp_warn = getdef_num("PASS_WARN_AGE", -1);
+ spent.sp_inact = -1;
+ spent.sp_expire = -1;
+ spent.sp_flag = -1;
+ }
+ spent.sp_pwdp = pw->pw_passwd;
+ spent.sp_lstchg = time((time_t *) 0) / (24L*3600L);
+ if (!spw_update(&spent)) {
+ fprintf(stderr,
+ _("%s: can't update shadow entry for %s\n"),
+ Prog, spent.sp_namp);
+ fail_exit(E_FAILURE);
+ }
+ /* remove password from /etc/passwd */
+ pwent = *pw;
+ pwent.pw_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
+ if (!pw_update(&pwent)) {
+ fprintf(stderr,
+ _("%s: can't update passwd entry for %s\n"),
+ Prog, pwent.pw_name);
+ fail_exit(E_FAILURE);
+ }
+ }
+
+ if (!spw_close()) {
+ fprintf(stderr, _("%s: can't update shadow file\n"), Prog);
+ fail_exit(E_FAILURE);
+ }
+ if (!pw_close()) {
+ fprintf(stderr, _("%s: can't update passwd file\n"), Prog);
+ fail_exit(E_FAILURE);
+ }
+ chmod(PASSWD_FILE "-", 0600); /* /etc/passwd- (backup file) */
+ spw_unlock();
+ pw_unlock();
+ exit(E_SUCCESS);
+}
diff --git a/current/src/pwunconv.c b/current/src/pwunconv.c
new file mode 100644
index 00000000..9335a489
--- /dev/null
+++ b/current/src/pwunconv.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * pwunconv - restore old password file from shadow password file.
+ *
+ * Pwunconv copies the password file information from the shadow
+ * password file, merging entries from an optional existing shadow
+ * file.
+ *
+ * Modifed by Guy Maor <maor@debian.org> to acquire necessary locks
+ * and modify the files in place.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: pwunconv.c,v 1.9 2000/08/26 18:27:18 marekm Exp $")
+
+#include "defines.h"
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <unistd.h>
+#include "prototypes.h"
+#include "pwio.h"
+#include "shadowio.h"
+
+#ifndef SHADOWPWD
+int
+main(int argc, char **argv)
+{
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ fprintf(stderr, _("%s: Shadow passwords are not configured.\n"),
+ argv[0]);
+ exit(1);
+}
+
+#else /*{*/
+
+char *l64a ();
+
+static int shadow_locked = 0,
+ passwd_locked = 0;
+
+/* local function prototypes */
+static void fail_exit(int);
+
+static void
+fail_exit(int status)
+{
+ if (shadow_locked)
+ spw_unlock();
+ if (passwd_locked)
+ pw_unlock();
+ exit(status);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ const struct passwd *pw;
+ struct passwd pwent;
+ const struct spwd *spwd;
+#ifdef ATT_AGE
+ char newage[5];
+#endif
+ char *Prog = argv[0];
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ if (!spw_file_present())
+ /* shadow not installed, do nothing */
+ exit(0);
+
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: can't lock passwd file\n"), Prog);
+ fail_exit(5);
+ }
+ passwd_locked++;
+ if (!pw_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open passwd file\n"), Prog);
+ fail_exit(1);
+ }
+
+ if (!spw_lock()) {
+ fprintf(stderr, _("%s: can't open shadow file\n"), Prog);
+ fail_exit(5);
+ }
+ shadow_locked++;
+ if (!spw_open(O_RDWR)) {
+ fprintf(stderr, _("%s: can't open shadow file\n"), Prog);
+ fail_exit(1);
+ }
+
+ pw_rewind();
+ while ((pw = pw_next())) {
+ if (!(spwd = spw_locate(pw->pw_name)))
+ continue;
+
+ pwent = *pw;
+
+ /*
+ * Update password if non-shadow is "x".
+ */
+ if (strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)
+ pwent.pw_passwd = spwd->sp_pwdp;
+
+ /*
+ * Password aging works differently in the two different systems.
+ * With shadow password files you apparently must have some aging
+ * information. The maxweeks or minweeks may not map exactly.
+ * In pwconv we set max == 10000, which is about 30 years. Here
+ * we have to undo that kludge. So, if maxdays == 10000, no aging
+ * information is put into the new file. Otherwise, the days are
+ * converted to weeks and so on.
+ */
+
+#ifdef ATT_AGE
+ if (spwd->sp_max > (63*WEEK/SCALE) && spwd->sp_max < 10000)
+ spwd->sp_max = (63*WEEK/SCALE); /* 10000 is infinity */
+
+ if (spwd->sp_min >= 0 && spwd->sp_min <= 63*7 &&
+ spwd->sp_max >= 0 && spwd->sp_max <= 63*7) {
+ if (spwd->sp_lstchg == -1)
+ spwd->sp_lstchg = 0;
+
+ spwd->sp_max /= WEEK/SCALE; /* turn it into weeks */
+ spwd->sp_min /= WEEK/SCALE;
+ spwd->sp_lstchg /= WEEK/SCALE;
+
+ strncpy (newage, l64a (spwd->sp_lstchg * (64L*64L) +
+ spwd->sp_min * (64L) + spwd->sp_max), 5);
+ pwent.pw_age = newage;
+ } else
+ pwent.pw_age = "";
+#endif /* ATT_AGE */
+ if (!pw_update(&pwent)) {
+ fprintf(stderr,
+ _("%s: can't update entry for user %s\n"),
+ Prog, pwent.pw_name);
+ fail_exit(3);
+ }
+ }
+
+ if (!spw_close()) {
+ fprintf(stderr, _("%s: can't update shadow password file\n"), Prog);
+ fail_exit(3);
+ }
+
+ if (!pw_close()) {
+ fprintf(stderr, _("%s: can't update password file\n"), Prog);
+ fail_exit(3);
+ }
+
+ if (unlink(SHADOW) != 0) {
+ fprintf(stderr, _("%s: can't delete shadow password file\n"), Prog);
+ fail_exit(3);
+ }
+
+ spw_unlock();
+ pw_unlock();
+ return 0;
+}
+#endif
diff --git a/current/src/shadowconfig.sh b/current/src/shadowconfig.sh
new file mode 100755
index 00000000..17b8aa9e
--- /dev/null
+++ b/current/src/shadowconfig.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# turn shadow passwords on or off on a Debian system
+
+set -e
+
+permfix () {
+ [ -f $1 ] || return 0
+ chown root:shadow $1
+ chmod 2755 $1
+}
+export -f permfix
+
+shadowon () {
+bash<<- EOF
+ set -e
+
+ permfix /usr/X11R6/bin/xlock
+ permfix /usr/X11R6/bin/xtrlock
+ permfix /bin/vlock
+
+ pwck -q
+ grpck
+ pwconv
+ grpconv
+ cd /etc
+ chown root:root passwd group
+ chmod 644 passwd group
+ chown root:shadow shadow gshadow
+ chmod 640 shadow gshadow
+EOF
+}
+
+shadowoff () {
+bash<<- EOF
+ set -e
+ pwck -q
+ grpck
+ pwunconv
+ grpunconv
+ cd /etc
+ # sometimes the passwd perms get munged
+ chown root:root passwd group
+ chmod 644 passwd group
+EOF
+}
+
+case "$1" in
+ "on")
+ if shadowon ; then
+ echo Shadow passwords are now on.
+ else
+ echo Please correct the error and rerun \`$0 on\'
+ exit 1
+ fi
+ ;;
+ "off")
+ if shadowoff ; then
+ echo Shadow passwords are now off.
+ else
+ echo Please correct the error and rerun \`$0 off\'
+ exit 1
+ fi
+ ;;
+ *)
+ echo Usage: $0 on \| off
+ ;;
+esac
diff --git a/current/src/su.c b/current/src/su.c
new file mode 100644
index 00000000..c8b88030
--- /dev/null
+++ b/current/src/su.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: su.c,v 1.15 2000/09/02 18:40:44 marekm Exp $")
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifdef USE_PAM
+#include "pam_defs.h"
+
+static const struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+static pam_handle_t *pamh = NULL;
+#endif
+
+#include "prototypes.h"
+#include "defines.h"
+
+#include <grp.h>
+#include <signal.h>
+#include <pwd.h>
+#include "pwauth.h"
+#include "getdef.h"
+
+/*
+ * Assorted #defines to control su's behavior
+ */
+
+/*
+ * Global variables
+ */
+
+/* not needed by sulog.c anymore */
+static char name[BUFSIZ];
+static char oldname[BUFSIZ];
+
+static char *Prog;
+
+struct passwd pwent;
+
+/*
+ * External identifiers
+ */
+
+extern char **newenvp;
+extern size_t newenvc;
+
+extern char **environ;
+
+/* local function prototypes */
+
+#ifndef USE_PAM
+
+static RETSIGTYPE die(int);
+static int iswheel(const char *);
+
+/*
+ * die - set or reset termio modes.
+ *
+ * die() is called before processing begins. signal() is then
+ * called with die() as the signal handler. If signal later
+ * calls die() with a signal number, the terminal modes are
+ * then reset.
+ */
+
+static RETSIGTYPE
+die(int killed)
+{
+ static TERMIO sgtty;
+
+ if (killed)
+ STTY(0, &sgtty);
+ else
+ GTTY(0, &sgtty);
+
+ if (killed) {
+ closelog();
+ exit(killed);
+ }
+}
+
+static int
+iswheel(const char *username)
+{
+ struct group *grp;
+
+ grp = getgrgid(0);
+ if (!grp || !grp->gr_mem)
+ return 0;
+ return is_on_list(grp->gr_mem, username);
+}
+#endif /* !USE_PAM */
+
+
+static void
+su_failure(const char *tty)
+{
+ sulog(tty, 0, oldname, name); /* log failed attempt */
+#ifdef USE_SYSLOG
+ if (getdef_bool("SYSLOG_SU_ENAB"))
+ SYSLOG((pwent.pw_uid ? LOG_INFO:LOG_NOTICE,
+ "- %s %s-%s\n", tty,
+ oldname[0] ? oldname:"???",
+ name[0] ? name:"???"));
+ closelog();
+#endif
+ puts(_("Sorry."));
+ exit(1);
+}
+
+
+/*
+ * su - switch user id
+ *
+ * su changes the user's ids to the values for the specified user.
+ * if no new user name is specified, "root" is used by default.
+ *
+ * The only valid option is a "-" character, which is interpreted
+ * as requiring a new login session to be simulated.
+ *
+ * Any additional arguments are passed to the user's shell. In
+ * particular, the argument "-c" will cause the next argument to
+ * be interpreted as a command by the common shell programs.
+ */
+
+int
+main(int argc, char **argv)
+{
+ char *cp;
+ const char *tty = 0; /* Name of tty SU is run from */
+ int doshell = 0;
+ int fakelogin = 0;
+ int amroot = 0;
+ uid_t my_uid;
+ struct passwd *pw = 0;
+ char **envp = environ;
+#ifdef USE_PAM
+ int ret;
+#else /* !USE_PAM */
+ RETSIGTYPE (*oldsig)();
+ int is_console = 0;
+#ifdef SHADOWPWD
+ struct spwd *spwd = 0;
+#endif
+#ifdef SU_ACCESS
+ char *oldpass;
+#endif
+#endif /* !USE_PAM */
+
+ sanitize_env();
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /*
+ * Get the program name. The program name is used as a
+ * prefix to most error messages.
+ */
+
+ Prog = Basename(argv[0]);
+
+ OPENLOG("su");
+
+ initenv();
+
+ my_uid = getuid();
+ amroot = (my_uid == 0);
+
+ /*
+ * Get the tty name. Entries will be logged indicating that
+ * the user tried to change to the named new user from the
+ * current terminal.
+ */
+
+ if (isatty(0) && (cp = ttyname(0))) {
+ if (strncmp (cp, "/dev/", 5) == 0)
+ tty = cp + 5;
+ else
+ tty = cp;
+#ifndef USE_PAM
+ is_console = console(tty);
+#endif
+ } else {
+ /*
+ * Be more paranoid, like su from SimplePAMApps. --marekm
+ */
+ if (!amroot) {
+ fprintf(stderr, _("%s: must be run from a terminal\n"),
+ Prog);
+ exit(1);
+ }
+ tty = "???";
+ }
+
+ /*
+ * Process the command line arguments.
+ */
+
+ argc--; argv++; /* shift out command name */
+
+ if (argc > 0 && strcmp(argv[0], "-") == 0) {
+ fakelogin = 1;
+ argc--; argv++; /* shift ... */
+ }
+
+ /*
+ * If a new login is being set up, the old environment will
+ * be ignored and a new one created later on.
+ */
+
+ if (fakelogin) {
+ if ((cp=getdef_str("ENV_TZ")))
+ addenv(*cp == '/' ? tz(cp) : cp, NULL);
+ /*
+ * The clock frequency will be reset to the login value if required
+ */
+ if ((cp=getdef_str("ENV_HZ")))
+ addenv(cp, NULL); /* set the default $HZ, if one */
+ /*
+ * The terminal type will be left alone if it is present in the
+ * environment already.
+ */
+ if ((cp = getenv ("TERM")))
+ addenv("TERM", cp);
+ } else {
+ while (*envp)
+ addenv(*envp++, NULL);
+ }
+
+ /*
+ * The next argument must be either a user ID, or some flag to
+ * a subshell. Pretty sticky since you can't have an argument
+ * which doesn't start with a "-" unless you specify the new user
+ * name. Any remaining arguments will be passed to the user's
+ * login shell.
+ */
+
+ if (argc > 0 && argv[0][0] != '-') {
+ STRFCPY(name, argv[0]); /* use this login id */
+ argc--; argv++; /* shift ... */
+ }
+ if (! name[0]) /* use default user ID */
+ (void) strcpy (name, "root");
+
+ doshell = argc == 0; /* any arguments remaining? */
+
+ /*
+ * Get the user's real name. The current UID is used to determine
+ * who has executed su. That user ID must exist.
+ */
+
+ pw = get_my_pwent();
+ if (!pw) {
+ SYSLOG((LOG_CRIT, "Unknown UID: %d\n", (int) my_uid));
+ su_failure(tty);
+ }
+ STRFCPY(oldname, pw->pw_name);
+
+#ifndef USE_PAM
+#ifdef SU_ACCESS
+ /*
+ * Sort out the password of user calling su, in case needed later
+ * -- chris
+ */
+#ifdef SHADOWPWD
+ if ((spwd = getspnam(oldname)))
+ pw->pw_passwd = spwd->sp_pwdp;
+#endif
+ oldpass = xstrdup(pw->pw_passwd);
+#endif /* SU_ACCESS */
+#endif /* !USE_PAM */
+
+#ifdef USE_PAM
+ ret = pam_start("su", name, &conv, &pamh);
+ if (ret != PAM_SUCCESS) {
+ SYSLOG((LOG_ERR, "pam_start: error %d\n", ret);
+ fprintf(stderr, _("%s: pam_start: error %d\n"), Prog, ret));
+ exit(1);
+ }
+
+ ret = pam_set_item(pamh, PAM_TTY, (const void *) tty);
+ if (ret == PAM_SUCCESS)
+ ret = pam_set_item(pamh, PAM_RUSER, (const void *) oldname);
+ if (ret != PAM_SUCCESS) {
+ SYSLOG((LOG_ERR, "pam_set_item: %s\n", PAM_STRERROR(pamh, ret)));
+ fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret));
+ pam_end(pamh, ret);
+ exit(1);
+ }
+#endif /* USE_PAM */
+
+top:
+ /*
+ * This is the common point for validating a user whose name
+ * is known. It will be reached either by normal processing,
+ * or if the user is to be logged into a subsystem root.
+ *
+ * The password file entries for the user is gotten and the
+ * account validated.
+ */
+
+ if (!(pw = getpwnam(name))) {
+ (void) fprintf (stderr, _("Unknown id: %s\n"), name);
+ closelog();
+ exit(1);
+ }
+
+#ifndef USE_PAM
+#ifdef SHADOWPWD
+ spwd = NULL;
+ if (strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING) == 0 && (spwd = getspnam(name)))
+ pw->pw_passwd = spwd->sp_pwdp;
+#endif
+#endif /* !USE_PAM */
+ pwent = *pw;
+
+#ifndef USE_PAM
+ /*
+ * BSD systems only allow "wheel" to SU to root. USG systems
+ * don't, so we make this a configurable option.
+ */
+
+ /* The original Shadow 3.3.2 did this differently. Do it like BSD:
+
+ - check for uid 0 instead of name "root" - there are systems
+ with several root accounts under different names,
+
+ - check the contents of /etc/group instead of the current group
+ set (you must be listed as a member, GID 0 is not sufficient).
+
+ In addition to this traditional feature, we now have complete
+ su access control (allow, deny, no password, own password).
+ Thanks to Chris Evans <lady0110@sable.ox.ac.uk>. */
+
+ if (!amroot) {
+ if (pwent.pw_uid == 0 && getdef_bool("SU_WHEEL_ONLY")
+ && !iswheel(oldname)) {
+ fprintf(stderr, _("You are not authorized to su %s\n"), name);
+ exit(1);
+ }
+#ifdef SU_ACCESS
+ switch (check_su_auth(oldname, name)) {
+ case 0: /* normal su, require target user's password */
+ break;
+ case 1: /* require no password */
+ pwent.pw_passwd = ""; /* XXX warning: const */
+ break;
+ case 2: /* require own password */
+ puts(_("(Enter your own password.)"));
+ pwent.pw_passwd = oldpass;
+ break;
+ default: /* access denied (-1) or unexpected value */
+ fprintf(stderr, _("You are not authorized to su %s\n"), name);
+ exit(1);
+ }
+#endif /* SU_ACCESS */
+ }
+#endif /* !USE_PAM */
+
+ /*
+ * Set the default shell.
+ */
+#if 0
+ /*
+ * XXX - GNU and *BSD versions of su support the -m option.
+ * Need to add some option parsing code.
+ */
+ if (mflg) {
+ if (!amroot && !check_shell(pwent.pw_shell)) {
+ fprintf(stderr, _("%s: permission denied (shell).\n"), Prog);
+ exit(1);
+ }
+ if ((cp = getenv("SHELL")))
+ pwent.pw_shell = cp;
+ }
+#endif
+
+ if (pwent.pw_shell[0] == '\0')
+ pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
+
+#ifdef USE_PAM
+ ret = pam_authenticate(pamh, 0);
+ if (ret != PAM_SUCCESS) {
+ SYSLOG((LOG_ERR, "pam_authenticate: %s\n",
+ PAM_STRERROR(pamh, ret)));
+ fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret));
+ pam_end(pamh, ret);
+ su_failure(tty);
+ }
+
+ ret = pam_acct_mgmt(pamh, 0);
+ if (ret != PAM_SUCCESS) {
+ if (amroot) {
+ fprintf(stderr, _("%s: %s\n(Ignored)\n"), Prog, PAM_STRERROR(pamh, ret));
+ } else {
+ SYSLOG((LOG_ERR, "pam_acct_mgmt: %s\n",
+ PAM_STRERROR(pamh, ret)));
+ fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret));
+ pam_end(pamh, ret);
+ su_failure(tty);
+ }
+ }
+#else /* !USE_PAM */
+ /*
+ * Set up a signal handler in case the user types QUIT.
+ */
+
+ die (0);
+ oldsig = signal (SIGQUIT, die);
+
+ /*
+ * See if the system defined authentication method is being used.
+ * The first character of an administrator defined method is an
+ * '@' character.
+ */
+
+ if (! amroot && pw_auth (pwent.pw_passwd, name, PW_SU, (char *) 0)) {
+ SYSLOG((pwent.pw_uid ? LOG_NOTICE:LOG_WARN,
+ "Authentication failed for %s\n", name));
+ su_failure(tty);
+ }
+ signal (SIGQUIT, oldsig);
+
+ /*
+ * Check to see if the account is expired. root gets to
+ * ignore any expired accounts, but normal users can't become
+ * a user with an expired password.
+ */
+
+ if (! amroot) {
+#ifdef SHADOWPWD
+ if (!spwd)
+ spwd = pwd_to_spwd(&pwent);
+
+ if (isexpired(&pwent, spwd)) {
+ SYSLOG((pwent.pw_uid ? LOG_WARN : LOG_CRIT,
+ "Expired account %s\n", name));
+ su_failure(tty);
+ }
+#else
+#if defined(ATT_AGE) && defined(AGING)
+ else if (pwent.pw_age[0] &&
+ isexpired (&pwent)) {
+ SYSLOG((pwent.pw_uid ? LOG_WARN:LOG_CRIT,
+ "Expired account %s\n", name));
+ su_failure(tty);
+ }
+#endif /* ATT_AGE */
+#endif
+ }
+
+ /*
+ * Check to see if the account permits "su". root gets to
+ * ignore any restricted accounts, but normal users can't become
+ * a user if there is a "SU" entry in the /etc/porttime file
+ * denying access to the account.
+ */
+
+ if (! amroot) {
+ if (! isttytime (pwent.pw_name, "SU", time ((time_t *) 0))) {
+ SYSLOG((pwent.pw_uid ? LOG_WARN : LOG_CRIT,
+ "SU by %s to restricted account %s\n",
+ oldname, name));
+ su_failure(tty);
+ }
+ }
+#endif /* !USE_PAM */
+
+ cp = getdef_str((pwent.pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
+#if 0
+ addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL);
+#else
+ /* XXX very similar code duplicated in libmisc/setupenv.c */
+ if (!cp) {
+ addenv("PATH=/bin:/usr/bin", NULL);
+ } else if (strchr(cp, '=')) {
+ addenv(cp, NULL);
+ } else {
+ addenv("PATH", cp);
+ }
+#endif
+
+ environ = newenvp; /* make new environment active */
+
+ if (getenv ("IFS")) /* don't export user IFS ... */
+ addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
+
+ if (pwent.pw_shell[0] == '*') { /* subsystem root required */
+ subsystem (&pwent); /* figure out what to execute */
+ endpwent ();
+#ifdef SHADOWPWD
+ endspent ();
+#endif
+ goto top;
+ }
+
+ sulog(tty, 1, oldname, name); /* save SU information */
+ endpwent ();
+#ifdef SHADOWPWD
+ endspent ();
+#endif
+#ifdef USE_SYSLOG
+ if (getdef_bool("SYSLOG_SU_ENAB"))
+ SYSLOG((LOG_INFO, "+ %s %s-%s\n", tty,
+ oldname[0] ? oldname:"???", name[0] ? name:"???"));
+#endif
+
+#ifdef USE_PAM
+ /* set primary group id and supplementary groups */
+ if (setup_groups(&pwent)) {
+ pam_end(pamh, PAM_ABORT);
+ exit(1);
+ }
+
+ /* pam_setcred() may do things like resource limits, console groups,
+ and much more, depending on the configured modules */
+ ret = pam_setcred(pamh, PAM_ESTABLISH_CRED);
+ if (ret != PAM_SUCCESS) {
+ SYSLOG((LOG_ERR, "pam_setcred: %s\n", PAM_STRERROR(pamh, ret)));
+ fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret));
+ pam_end(pamh, ret);
+ exit(1);
+ }
+
+ /* become the new user */
+ if (change_uid(&pwent)) {
+ pam_setcred(pamh, PAM_DELETE_CRED);
+ pam_end(pamh, PAM_ABORT);
+ exit(1);
+ }
+
+ /* now we are done using PAM */
+ pam_end(pamh, PAM_SUCCESS);
+
+#else /* !USE_PAM */
+ if (!amroot) /* no limits if su from root */
+ setup_limits(&pwent);
+
+ if (setup_uid_gid(&pwent, is_console))
+ exit(1);
+#endif /* !USE_PAM */
+
+ if (fakelogin)
+ setup_env(&pwent);
+#if 1 /* Suggested by Joey Hess. XXX - is this right? */
+ else
+ addenv("HOME", pwent.pw_dir);
+#endif
+
+ /*
+ * This is a workaround for Linux libc bug/feature (?) - the
+ * /dev/log file descriptor is open without the close-on-exec
+ * flag and used to be passed to the new shell. There is
+ * "fcntl(LogFile, F_SETFD, 1)" in libc/misc/syslog.c, but
+ * it is commented out (at least in 5.4.33). Why? --marekm
+ */
+ closelog();
+
+ /*
+ * See if the user has extra arguments on the command line. In
+ * that case they will be provided to the new user's shell as
+ * arguments.
+ */
+
+ if (fakelogin) {
+ char *arg0;
+
+#if 0 /* XXX - GNU su doesn't do this. --marekm */
+ if (! hushed (&pwent)) {
+ motd ();
+ mailcheck ();
+ }
+#endif
+ cp = getdef_str("SU_NAME");
+ if (!cp)
+ cp = Basename(pwent.pw_shell);
+
+ arg0 = xmalloc(strlen(cp) + 2);
+ arg0[0] = '-';
+ strcpy(arg0 + 1, cp);
+ cp = arg0;
+ } else
+ cp = Basename(pwent.pw_shell);
+
+ if (! doshell) {
+
+ /*
+ * Use new user's shell from /etc/passwd and create an
+ * argv with the rest of the command line included.
+ */
+
+ argv[-1] = pwent.pw_shell;
+ (void) execv (pwent.pw_shell, &argv[-1]);
+ (void) fprintf (stderr, _("No shell\n"));
+ SYSLOG((LOG_WARN, "Cannot execute %s\n", pwent.pw_shell));
+ closelog();
+ exit (1);
+ }
+
+ shell(pwent.pw_shell, cp);
+ /*NOTREACHED*/
+ exit(1);
+}
diff --git a/current/src/sulogin.c b/current/src/sulogin.c
new file mode 100644
index 00000000..e33aec62
--- /dev/null
+++ b/current/src/sulogin.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: sulogin.c,v 1.12 2000/09/02 18:40:44 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include "getdef.h"
+
+#if HAVE_UTMPX_H
+#include <utmpx.h>
+#else
+#include <utmp.h>
+#endif
+
+#include <signal.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include "pwauth.h"
+
+static char name[BUFSIZ];
+static char pass[BUFSIZ];
+
+static struct passwd pwent;
+#if 0
+#if HAVE_UTMPX_H
+static struct utmpx utent;
+#else
+static struct utmp utent;
+#endif
+#endif
+
+
+extern char **newenvp;
+extern size_t newenvc;
+
+extern char **environ;
+
+#ifndef ALARM
+#define ALARM 60
+#endif
+
+/* local function prototypes */
+static RETSIGTYPE catch(int);
+
+static RETSIGTYPE
+catch(int sig)
+{
+ exit(1);
+}
+
+/* syslogd is usually not running at the time when sulogin is typically
+ called, cluttering the screen with unnecessary messages. Suggested
+ by Ivan Nejgebauer <ian@unsux.ns.ac.yu>. --marekm */
+#undef USE_SYSLOG
+
+/*ARGSUSED*/
+int
+main(int argc, char **argv)
+{
+ char *cp;
+ char **envp = environ;
+ TERMIO termio;
+
+#ifdef USE_TERMIO
+ ioctl (0, TCGETA, &termio);
+ termio.c_iflag |= (ICRNL|IXON);
+ termio.c_oflag |= (OPOST|ONLCR);
+ termio.c_cflag |= (CREAD);
+ termio.c_lflag |= (ISIG|ICANON|ECHO|ECHOE|ECHOK);
+ ioctl (0, TCSETAF, &termio);
+#endif
+#ifdef USE_TERMIOS
+ tcgetattr (0, &termio);
+ termio.c_iflag |= (ICRNL|IXON);
+ termio.c_oflag |= (CREAD);
+ termio.c_lflag |= (ECHO|ECHOE|ECHOK|ICANON|ISIG);
+ tcsetattr (0, TCSANOW, &termio);
+#endif
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+#ifdef USE_SYSLOG
+ OPENLOG("sulogin");
+#endif
+ initenv();
+ if (argc > 1) {
+ close (0);
+ close (1);
+ close (2);
+
+ if (open (argv[1], O_RDWR) >= 0) {
+ dup (0);
+ dup (0);
+ } else {
+#ifdef USE_SYSLOG
+ syslog (LOG_WARN, "cannot open %s\n", argv[1]);
+ closelog ();
+#endif
+ exit (1);
+ }
+ }
+ if (access(PASSWD_FILE, F_OK) == -1) { /* must be a password file! */
+ printf(_("No password file\n"));
+#ifdef USE_SYSLOG
+ syslog(LOG_WARN, "No password file\n");
+ closelog ();
+#endif
+ exit (1);
+ }
+#if !defined(DEBUG) && defined(SULOGIN_ONLY_INIT)
+ if (getppid () != 1) { /* parent must be INIT */
+#ifdef USE_SYSLOG
+ syslog (LOG_WARN, "Pid == %d, not 1\n", getppid ());
+ closelog ();
+#endif
+ exit (1);
+ }
+#endif
+ if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
+#ifdef USE_SYSLOG
+ closelog ();
+#endif
+ exit (1); /* must be a terminal */
+ }
+ while (*envp) /* add inherited environment, */
+ addenv(*envp++, NULL); /* some variables change later */
+
+ if ((cp = getdef_str("ENV_TZ")))
+ addenv(*cp == '/' ? tz(cp) : cp, NULL);
+ if ((cp = getdef_str("ENV_HZ")))
+ addenv(cp, NULL); /* set the default $HZ, if one */
+ (void) strcpy (name, "root"); /* KLUDGE!!! */
+
+ signal (SIGALRM, catch); /* exit if the timer expires */
+ alarm (ALARM); /* only wait so long ... */
+
+ while (1) { /* repeatedly get login/password pairs */
+ pw_entry(name, &pwent); /* get entry from password file */
+ if (pwent.pw_name == (char *) 0) {
+
+ /*
+ * Fail secure
+ */
+
+ printf(_("No password entry for 'root'\n"));
+#ifdef USE_SYSLOG
+ syslog (LOG_WARN, "No password entry for 'root'\n");
+ closelog ();
+#endif
+ exit (1);
+ }
+
+ /*
+ * Here we prompt for the root password, or if no password is
+ * given we just exit.
+ */
+
+ /* get a password for root */
+ cp = getpass(_("\nType control-d to proceed with normal startup,\n(or give root password for system maintenance):"));
+ /*
+ * XXX - can't enter single user mode if root password is empty.
+ * I think this doesn't happen very often :-). But it will work
+ * with standard getpass() (no NULL on EOF). --marekm
+ */
+ if (!cp || !*cp) {
+#ifdef USE_SYSLOG
+ syslog (LOG_INFO, "Normal startup\n");
+ closelog ();
+#endif
+ puts("\n");
+#ifdef TELINIT
+ execl (PATH_TELINIT, "telinit", RUNLEVEL, (char *) 0);
+#endif
+ exit (0);
+ } else {
+ STRFCPY(pass, cp);
+ strzero(cp);
+ }
+#ifdef AUTH_METHODS
+ if (pwent.pw_name && pwent.pw_passwd[0] == '@') {
+ if (pw_auth (pwent.pw_passwd + 1, name, PW_LOGIN, (char *) 0)) {
+#ifdef USE_SYSLOG
+ syslog (LOG_WARN,
+ "Incorrect root authentication");
+#endif
+ continue;
+ }
+ goto auth_done;
+ }
+#endif
+ if (valid (pass, &pwent)) /* check encrypted passwords ... */
+ break; /* ... encrypted passwords matched */
+
+#ifdef USE_SYSLOG
+ syslog (LOG_WARN, "Incorrect root password\n");
+#endif
+ sleep(2);
+ puts (_("Login incorrect"));
+ }
+#ifdef AUTH_METHODS
+auth_done:
+#endif
+ strzero(pass);
+ alarm (0);
+ signal (SIGALRM, SIG_DFL);
+ environ = newenvp; /* make new environment active */
+
+ puts(_("Entering System Maintenance Mode\n"));
+#ifdef USE_SYSLOG
+ syslog (LOG_INFO, "System Maintenance Mode\n");
+#endif
+
+#if 0 /* do we need all this? we are logging in as root anyway... --marekm */
+ /*
+ * Normally there would be a utmp entry for login to mung on
+ * to get the tty name, date, etc. from. We don't need all that
+ * stuff because we won't update the utmp or wtmp files. BUT!,
+ * we do need the tty name so we can set the permissions and
+ * ownership.
+ */
+
+ if ((cp = ttyname (0))) { /* found entry in /dev/ */
+ if (strncmp(cp, "/dev/", 5) == 0)
+ cp += 5;
+
+ strncpy(utent.ut_line, cp, sizeof utent.ut_line);
+ }
+ if (getenv ("IFS")) /* don't export user IFS ... */
+ addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
+
+ setup (&pwent, 0); /* set UID, GID, HOME, etc ... */
+#endif
+
+#ifdef USE_SYSLOG
+ closelog ();
+#endif
+ shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
+ /*NOTREACHED*/
+ return (0);
+}
diff --git a/current/src/useradd.c b/current/src/useradd.c
new file mode 100644
index 00000000..880d854e
--- /dev/null
+++ b/current/src/useradd.c
@@ -0,0 +1,1746 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: useradd.c,v 1.18 2000/09/02 18:40:44 marekm Exp $")
+
+#include "prototypes.h"
+#include "defines.h"
+#include "chkname.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include "pwauth.h"
+#if HAVE_LASTLOG_H
+#include <lastlog.h>
+#else
+#include "lastlog_.h"
+#endif
+#include "faillog.h"
+
+#ifndef SKEL_DIR
+#define SKEL_DIR "/etc/skel"
+#endif
+
+#ifndef USER_DEFAULTS_FILE
+#define USER_DEFAULTS_FILE "/etc/default/useradd"
+#define NEW_USER_FILE "/etc/default/nuaddXXXXXX"
+#endif
+
+/*
+ * Needed for MkLinux DR1/2/2.1 - J.
+ */
+#ifndef LASTLOG_FILE
+#define LASTLOG_FILE "/var/log/lastlog"
+#endif
+
+/*
+ * These defaults are used if there is no defaults file.
+ */
+static gid_t def_group = 100;
+static const char *def_gname = "other";
+static const char *def_home = "/home";
+static const char *def_shell = "";
+static const char *def_template = SKEL_DIR;
+#ifdef SHADOWPWD
+static long def_inactive = -1;
+static const char *def_expire = "";
+#endif
+
+static char def_file[] = USER_DEFAULTS_FILE;
+
+#define VALID(s) (strcspn (s, ":\n") == strlen (s))
+
+static const char *user_name = "";
+static const char *user_pass = "!";
+static uid_t user_id;
+static gid_t user_gid;
+static const char *user_comment = "";
+static const char *user_home = "";
+static const char *user_shell = "";
+#ifdef SHADOWPWD
+static long user_expire = -1;
+static int is_shadow_pwd;
+#endif
+#ifdef SHADOWGRP
+static int is_shadow_grp;
+#endif
+static char *user_groups[NGROUPS_MAX+1]; /* NULL-terminated list */
+static int do_grp_update = 0; /* group files need to be updated */
+
+static char *Prog;
+
+static int
+ uflg = 0, /* specify user ID for new account */
+ oflg = 0, /* permit non-unique user ID to be specified with -u */
+ gflg = 0, /* primary group ID for new account */
+ Gflg = 0, /* secondary group set for new account */
+ dflg = 0, /* home directory for new account */
+ bflg = 0, /* new default root of home directory */
+ sflg = 0, /* shell program for new account */
+ cflg = 0, /* comment (GECOS) field for new account */
+ mflg = 0, /* create user's home directory if it doesn't exist */
+ kflg = 0, /* specify a directory to fill new user directory */
+ fflg = 0, /* days until account with expired password is locked */
+ eflg = 0, /* days since 1970-01-01 when account is locked */
+ Dflg = 0; /* set/show new user default values */
+
+#ifdef AUTH_METHODS
+static int Aflg = 0; /* specify authentication method for user */
+static char user_auth[1024];
+static char *auth_arg;
+#endif
+
+extern char *optarg;
+extern int optind;
+
+#ifdef NDBM
+extern int pw_dbm_mode;
+#ifdef SHADOWPWD
+extern int sp_dbm_mode;
+#endif
+extern int gr_dbm_mode;
+#ifdef SHADOWGRP
+extern int sg_dbm_mode;
+#endif
+#endif
+
+static int home_added;
+
+#ifdef NDBM
+static int pw_dbm_added;
+static int gr_dbm_added;
+#ifdef SHADOWPWD
+static int sp_dbm_added;
+#endif
+#ifdef SHADOWGRP
+static int sg_dbm_added;
+#endif
+#endif /* NDBM */
+
+#include "groupio.h"
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+#endif
+
+#include "pwio.h"
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+
+#include "getdef.h"
+
+/*
+ * exit status values
+ */
+#define E_SUCCESS 0 /* success */
+#define E_PW_UPDATE 1 /* can't update password file */
+#define E_USAGE 2 /* bad command syntax */
+#define E_BAD_ARG 3 /* invalid argument to option */
+#define E_UID_IN_USE 4 /* uid already in use (and no -o) */
+#define E_NOTFOUND 6 /* specified group doesn't exist */
+#define E_NAME_IN_USE 9 /* username already in use */
+#define E_GRP_UPDATE 10 /* can't update group file */
+#define E_HOMEDIR 12 /* can't create home directory */
+
+#ifdef SVR4
+#define DGROUP "defgroup="
+#define HOME "defparent="
+#define SHELL "defshell="
+#define INACT "definact="
+#define EXPIRE "defexpire="
+#define SKEL "defskel="
+#else
+#define DGROUP "GROUP="
+#define HOME "HOME="
+#define SHELL "SHELL="
+#define INACT "INACTIVE="
+#define EXPIRE "EXPIRE="
+#define SKEL "SKEL="
+#endif
+
+/* local function prototypes */
+static void fail_exit(int);
+static struct group *getgr_nam_gid(const char *);
+static long get_number(const char *);
+static void get_defaults(void);
+static void show_defaults(void);
+static int set_defaults(void);
+static int get_groups(char *);
+static void usage(void);
+static void new_pwent(struct passwd *);
+#ifdef SHADOWPWD
+static long scale_age(long);
+static void new_spent(struct spwd *);
+#endif
+static void grp_update(void);
+static void find_new_uid(void);
+#ifdef AUTH_METHODS
+static void convert_auth(char *, const char *);
+static int valid_auth(const char *);
+#endif
+static void process_flags(int argc, char **argv);
+static void close_files(void);
+static void open_files(void);
+static void faillog_reset(uid_t);
+static void lastlog_reset(uid_t);
+static void usr_update(void);
+static void create_home(void);
+
+/*
+ * fail_exit - undo as much as possible
+ */
+
+static void
+fail_exit(int code)
+{
+#ifdef NDBM
+ struct passwd pwent;
+
+ if (pw_dbm_added) {
+ pwent.pw_name = user_name;
+ pwent.pw_uid = user_id;
+ pw_dbm_remove(&pwent);
+ }
+ if (gr_dbm_added)
+ fprintf(stderr, _("%s: rebuild the group database\n"), Prog);
+#ifdef SHADOWPWD
+ if (sp_dbm_added)
+ sp_dbm_remove(user_name);
+#endif
+#ifdef SHADOWGRP
+ if (sg_dbm_added)
+ fprintf(stderr, _("%s: rebuild the shadow group database\n"),
+ Prog);
+#endif
+#endif /* NDBM */
+ if (home_added)
+ rmdir(user_home);
+
+ SYSLOG((LOG_INFO, "failed adding user `%s', data deleted\n",
+ user_name));
+ exit(code);
+}
+
+
+static struct group *
+getgr_nam_gid(const char *name)
+{
+ gid_t gid;
+ char *ep;
+
+ gid = strtol(name, &ep, 10);
+ if (*name != '\0' && *ep == '\0') /* valid numeric gid */
+ return getgrgid(gid);
+
+ return getgrnam(name);
+}
+
+
+static long
+get_number(const char *cp)
+{
+ long val;
+ char *ep;
+
+ val = strtol(cp, &ep, 10);
+ if (*cp != '\0' && *ep == '\0') /* valid number */
+ return val;
+
+ fprintf(stderr, _("%s: invalid numeric argument `%s'\n"), Prog, cp);
+ exit(E_BAD_ARG);
+}
+
+#define MATCH(x,y) (strncmp((x),(y),strlen(y)) == 0)
+
+/*
+ * get_defaults - read the defaults file
+ *
+ * get_defaults() reads the defaults file for this command. It sets
+ * the various values from the file, or uses built-in default values
+ * if the file does not exist.
+ */
+
+static void
+get_defaults(void)
+{
+ FILE *fp;
+ char buf[1024];
+ char *cp, *ep;
+ const struct group *grp;
+ long val;
+
+ /*
+ * Open the defaults file for reading.
+ */
+
+ if (!(fp = fopen(def_file, "r")))
+ return;
+
+ /*
+ * Read the file a line at a time. Only the lines that have
+ * relevant values are used, everything else can be ignored.
+ */
+
+ while (fgets(buf, sizeof buf, fp)) {
+ if ((cp = strrchr (buf, '\n')))
+ *cp = '\0';
+
+ if (!(cp = strchr(buf, '=')))
+ continue;
+
+ cp++;
+
+ /*
+ * Primary GROUP identifier
+ */
+
+ if (MATCH(buf, DGROUP)) {
+ val = strtol(cp, &ep, 10);
+ if (*cp != '\0' && *ep == '\0') { /* valid number */
+ def_group = val;
+ if ((grp = getgrgid(def_group))) {
+ def_gname = xstrdup(grp->gr_name);
+ } else {
+ fprintf(stderr,
+ _("%s: unknown gid %s\n"),
+ Prog, cp);
+ }
+ } else if ((grp = getgrnam(cp))) {
+ def_group = grp->gr_gid;
+ def_gname = xstrdup(cp);
+ } else {
+ fprintf(stderr, _("%s: unknown group %s\n"),
+ Prog, cp);
+ }
+ }
+
+ /*
+ * Default HOME filesystem
+ */
+
+ else if (MATCH(buf, HOME)) {
+ def_home = xstrdup(cp);
+ }
+
+ /*
+ * Default Login Shell command
+ */
+
+ else if (MATCH(buf, SHELL)) {
+ def_shell = xstrdup(cp);
+ }
+
+#ifdef SHADOWPWD
+ /*
+ * Default Password Inactive value
+ */
+
+ else if (MATCH(buf, INACT)) {
+ val = strtol(cp, &ep, 10);
+ if (*cp != '\0' && *ep == '\0') /* valid number */
+ def_inactive = val;
+ else
+ def_inactive = -1;
+ }
+
+ /*
+ * Default account expiration date
+ */
+
+ else if (MATCH(buf, EXPIRE)) {
+ def_expire = xstrdup(cp);
+ }
+#endif
+
+ /*
+ * Default Skeleton information
+ */
+
+ else if (MATCH(buf, SKEL)) {
+ if (*cp == '\0')
+ cp = SKEL_DIR; /* XXX warning: const */
+
+ def_template = xstrdup(cp);
+ }
+ }
+}
+
+
+/*
+ * show_defaults - show the contents of the defaults file
+ *
+ * show_defaults() displays the values that are used from the default
+ * file and the built-in values.
+ */
+
+static void
+show_defaults(void)
+{
+#ifdef SVR4
+ printf(_("group=%s,%ld basedir=%s skel=%s\n"),
+ def_gname, (long) def_group, def_home, def_template);
+
+ printf(_("shell=%s "), def_shell);
+#ifdef SHADOWPWD
+ printf(_("inactive=%ld expire=%s"), def_inactive, def_expire);
+#endif
+ printf("\n");
+#else /* !SVR4 */
+ printf(_("GROUP=%ld\n"), (long) def_group);
+ printf(_("HOME=%s\n"), def_home);
+#ifdef SHADOWPWD
+ printf(_("INACTIVE=%ld\n"), def_inactive);
+ printf(_("EXPIRE=%s\n"), def_expire);
+#endif
+ printf(_("SHELL=%s\n"), def_shell);
+ printf(_("SKEL=%s\n"), def_template);
+#endif /* !SVR4 */
+}
+
+/*
+ * set_defaults - write new defaults file
+ *
+ * set_defaults() re-writes the defaults file using the values that
+ * are currently set. Duplicated lines are pruned, missing lines are
+ * added, and unrecognized lines are copied as is.
+ */
+
+static int
+set_defaults(void)
+{
+ FILE *ifp;
+ FILE *ofp;
+ char buf[1024];
+ static char new_file[] = NEW_USER_FILE;
+ char *cp;
+ int out_group = 0;
+ int out_home = 0;
+ int out_inactive = 0;
+ int out_expire = 0;
+ int out_shell = 0;
+ int out_skel = 0;
+#ifdef SVR4
+ int out_gname = 0;
+#endif
+
+ /*
+ * Create a temporary file to copy the new output to.
+ */
+
+ mktemp (new_file);
+ if (!(ofp = fopen (new_file, "w"))) {
+ fprintf(stderr, _("%s: cannot create new defaults file\n"),
+ Prog);
+ return -1;
+ }
+
+ /*
+ * Open the existing defaults file and copy the lines to the
+ * temporary file, using any new values. Each line is checked
+ * to insure that it is not output more than once.
+ */
+
+ if (!(ifp = fopen(def_file, "r"))) {
+ fprintf(ofp, "# useradd defaults file\n");
+ goto skip;
+ }
+
+ while (fgets(buf, sizeof buf, ifp)) {
+ if ((cp = strrchr(buf, '\n')))
+ *cp = '\0';
+
+ if (!out_group && MATCH(buf, DGROUP)) {
+ fprintf(ofp, DGROUP "%d\n", (int) def_group);
+ out_group++;
+ }
+#ifdef SVR4
+ else if (!out_gname && MATCH(buf, "defgname=")) {
+ fprintf(ofp, "defgname=%s\n", def_gname);
+ out_gname++;
+ }
+#endif
+ else if (!out_home && MATCH(buf, HOME)) {
+ fprintf(ofp, HOME "%s\n", def_home);
+ out_home++;
+#ifdef SHADOWPWD
+ } else if (!out_inactive && MATCH(buf, INACT)) {
+ fprintf(ofp, INACT "%ld\n", def_inactive);
+ out_inactive++;
+ } else if (!out_expire && MATCH(buf, EXPIRE)) {
+ fprintf(ofp, EXPIRE "%s\n", def_expire);
+ out_expire++;
+ }
+#endif
+ else if (!out_shell && MATCH(buf, SHELL)) {
+ fprintf(ofp, SHELL "%s\n", def_shell);
+ out_shell++;
+ }
+ else if (!out_skel && MATCH(buf, SKEL)) {
+ fprintf(ofp, SKEL "%s\n", def_template);
+ out_skel++;
+ }
+ else
+ fprintf(ofp, "%s\n", buf);
+ }
+ fclose(ifp);
+
+skip:
+ /*
+ * Check each line to insure that every line was output. This
+ * causes new values to be added to a file which did not previously
+ * have an entry for that value.
+ */
+
+ if (!out_group)
+ fprintf(ofp, DGROUP "%d\n", (int) def_group);
+ if (!out_home)
+ fprintf(ofp, HOME "%s\n", def_home);
+#ifdef SHADOWPWD
+ if (!out_inactive)
+ fprintf(ofp, INACT "%ld\n", def_inactive);
+ if (!out_expire)
+ fprintf(ofp, EXPIRE "%s\n", def_expire);
+#endif
+ if (!out_shell)
+ fprintf(ofp, SHELL "%s\n", def_shell);
+ if (!out_skel)
+ fprintf(ofp, SKEL "%s\n", def_template);
+
+ /*
+ * Flush and close the file. Check for errors to make certain
+ * the new file is intact.
+ */
+
+ fflush(ofp);
+ if (ferror(ofp) || fclose(ofp)) {
+ unlink(new_file);
+ return -1;
+ }
+
+ /*
+ * Rename the current default file to its backup name.
+ */
+
+ snprintf(buf, sizeof buf, "%s-", def_file);
+ if (rename(def_file, buf) && errno != ENOENT) {
+ snprintf(buf, sizeof buf, _("%s: rename: %s"), Prog, def_file);
+ perror(buf);
+ unlink(new_file);
+ return -1;
+ }
+
+ /*
+ * Rename the new default file to its correct name.
+ */
+
+ if (rename(new_file, def_file)) {
+ snprintf(buf, sizeof buf, _("%s: rename: %s"), Prog, new_file);
+ perror(buf);
+ return -1;
+ }
+#ifdef SHADOWPWD
+ SYSLOG((LOG_INFO,
+ "defaults: group=%d, home=%s, inactive=%ld, expire=%s\n",
+ (int) def_group, def_home, def_inactive, def_expire));
+#else
+ SYSLOG((LOG_INFO, "defaults: group=%d, home=%s\n",
+ (int) def_group, def_home));
+#endif
+ return 0;
+}
+
+/*
+ * get_groups - convert a list of group names to an array of group IDs
+ *
+ * get_groups() takes a comma-separated list of group names and
+ * converts it to a NULL-terminated array. Any unknown group
+ * names are reported as errors.
+ */
+
+static int
+get_groups(char *list)
+{
+ char *cp;
+ const struct group *grp;
+ int errors = 0;
+ int ngroups = 0;
+
+ /*
+ * Initialize the list to be empty
+ */
+
+ user_groups[0] = (char *) 0;
+
+ if (! *list)
+ return 0;
+
+ /*
+ * So long as there is some data to be converted, strip off
+ * each name and look it up. A mix of numerical and string
+ * values for group identifiers is permitted.
+ */
+
+ do {
+ /*
+ * Strip off a single name from the list
+ */
+
+ if ((cp = strchr (list, ',')))
+ *cp++ = '\0';
+
+ /*
+ * Names starting with digits are treated as numerical
+ * GID values, otherwise the string is looked up as is.
+ */
+
+ grp = getgr_nam_gid(list);
+
+ /*
+ * There must be a match, either by GID value or by
+ * string name.
+ */
+
+ if (! grp) {
+ fprintf(stderr, _("%s: unknown group %s\n"),
+ Prog, list);
+ errors++;
+ }
+ list = cp;
+
+ /*
+ * If the group doesn't exist, don't dump core...
+ * Instead, try the next one. --marekm
+ */
+ if (! grp)
+ continue;
+
+#ifdef USE_NIS
+ /*
+ * Don't add this group if they are an NIS group. Tell
+ * the user to go to the server for this group.
+ */
+
+ if (__isgrNIS ()) {
+ fprintf(stderr, _("%s: group `%s' is a NIS group.\n"),
+ Prog, grp->gr_name);
+ continue;
+ }
+#endif
+
+ if (ngroups == NGROUPS_MAX) {
+ fprintf(stderr,
+ _("%s: too many groups specified (max %d).\n"),
+ Prog, ngroups);
+ break;
+ }
+
+ /*
+ * Add the group name to the user's list of groups.
+ */
+
+ user_groups[ngroups++] = xstrdup(grp->gr_name);
+ } while (list);
+
+ user_groups[ngroups] = (char *) 0;
+
+ /*
+ * Any errors in finding group names are fatal
+ */
+
+ if (errors)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ _("usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"),
+ Prog);
+ fprintf(stderr,
+ _("\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n"));
+ fprintf(stderr, "\t\t");
+#ifdef SHADOWPWD
+ fprintf(stderr, _("[-f inactive] [-e expire ] "));
+#endif
+#ifdef AUTH_METHODS
+ fprintf(stderr, _("[-A program] "));
+#endif
+ fprintf(stderr, _("[-p passwd] name\n"));
+
+ fprintf(stderr, _(" %s\t-D [-g group] [-b base] [-s shell]\n"),
+ Prog);
+#ifdef SHADOWPWD
+ fprintf(stderr, _("\t\t[-f inactive] [-e expire ]\n"));
+#endif
+
+ exit(E_USAGE);
+}
+
+/*
+ * new_pwent - initialize the values in a password file entry
+ *
+ * new_pwent() takes all of the values that have been entered and
+ * fills in a (struct passwd) with them.
+ */
+
+static void
+new_pwent(struct passwd *pwent)
+{
+ memzero(pwent, sizeof *pwent);
+ pwent->pw_name = (char *) user_name;
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ pwent->pw_passwd = (char *) SHADOW_PASSWD_STRING;
+ else
+#endif
+ pwent->pw_passwd = (char *) user_pass;
+
+#ifdef ATT_AGE
+ pwent->pw_age = (char *) "";
+#endif
+ pwent->pw_uid = user_id;
+ pwent->pw_gid = user_gid;
+ pwent->pw_gecos = (char *) user_comment;
+#ifdef ATT_COMMENT
+ pwent->pw_comment = (char *) "";
+#endif
+#ifdef BSD_QUOTA
+ pwent->pw_quota = 0;
+#endif
+ pwent->pw_dir = (char *) user_home;
+ pwent->pw_shell = (char *) user_shell;
+}
+
+#ifdef SHADOWPWD
+static long
+scale_age(long x)
+{
+ if (x <= 0)
+ return x;
+
+ return x * (DAY/SCALE);
+}
+
+/*
+ * new_spent - initialize the values in a shadow password file entry
+ *
+ * new_spent() takes all of the values that have been entered and
+ * fills in a (struct spwd) with them.
+ */
+
+static void
+new_spent(struct spwd *spent)
+{
+ memzero(spent, sizeof *spent);
+ spent->sp_namp = (char *) user_name;
+ spent->sp_pwdp = (char *) user_pass;
+ spent->sp_lstchg = time((time_t *) 0) / SCALE;
+ spent->sp_min = scale_age(getdef_num("PASS_MIN_DAYS", -1));
+ spent->sp_max = scale_age(getdef_num("PASS_MAX_DAYS", -1));
+ spent->sp_warn = scale_age(getdef_num("PASS_WARN_AGE", -1));
+ spent->sp_inact = scale_age(def_inactive);
+ spent->sp_expire = scale_age(user_expire);
+ spent->sp_flag = -1;
+}
+#endif
+
+/*
+ * grp_update - add user to secondary group set
+ *
+ * grp_update() takes the secondary group set given in user_groups
+ * and adds the user to each group given by that set.
+ */
+
+static void
+grp_update(void)
+{
+ const struct group *grp;
+ struct group *ngrp;
+#ifdef SHADOWGRP
+ const struct sgrp *sgrp;
+ struct sgrp *nsgrp;
+#endif
+
+ /*
+ * Lock and open the group file. This will load all of the group
+ * entries.
+ */
+
+ if (! gr_lock ()) {
+ fprintf(stderr, _("%s: error locking group file\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (! gr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: error opening group file\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow_grp && ! sgr_lock ()) {
+ fprintf(stderr, _("%s: error locking shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp && ! sgr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: error opening shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#endif
+
+ /*
+ * Scan through the entire group file looking for the groups that
+ * the user is a member of.
+ */
+
+ for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
+
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+
+ if (!is_on_list(user_groups, grp->gr_name))
+ continue;
+
+ /*
+ * Make a copy - gr_update() will free() everything
+ * from the old entry, and we need it later.
+ */
+
+ ngrp = __gr_dup(grp);
+ if (!ngrp) {
+ fail_exit(E_GRP_UPDATE); /* XXX */
+ }
+
+ /*
+ * Add the username to the list of group members and
+ * update the group entry to reflect the change.
+ */
+
+ ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
+ if (!gr_update(ngrp)) {
+ fprintf(stderr, "%s: error adding new group entry\n",
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef NDBM
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+ if (!gr_dbm_update(ngrp)) {
+ fprintf(stderr, "%s: cannot add new dbm group entry\n",
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ } else
+ gr_dbm_added++;
+#endif
+ SYSLOG((LOG_INFO, "add `%s' to group `%s'\n",
+ user_name, ngrp->gr_name));
+ }
+#ifdef NDBM
+ endgrent ();
+#endif
+
+#ifdef SHADOWGRP
+ if (!is_shadow_grp)
+ return;
+
+ /*
+ * Scan through the entire shadow group file looking for the groups
+ * that the user is a member of. The administrative list isn't
+ * modified.
+ */
+
+ for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
+
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+
+ if (!gr_locate(sgrp->sg_name))
+ continue;
+
+ if (!is_on_list(user_groups, sgrp->sg_name))
+ continue;
+
+ /*
+ * Make a copy - sgr_update() will free() everything
+ * from the old entry, and we need it later.
+ */
+
+ nsgrp = __sgr_dup(sgrp);
+ if (!nsgrp) {
+ fail_exit(E_GRP_UPDATE); /* XXX */
+ }
+
+ /*
+ * Add the username to the list of group members and
+ * update the group entry to reflect the change.
+ */
+
+ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
+ if (!sgr_update(nsgrp)) {
+ fprintf(stderr,
+ _("%s: error adding new group entry\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef NDBM
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+ if (!sg_dbm_update(nsgrp)) {
+ fprintf(stderr,
+ _("%s: cannot add new dbm group entry\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ } else
+ sg_dbm_added++;
+#endif /* NDBM */
+ SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n",
+ user_name, nsgrp->sg_name));
+ }
+#ifdef NDBM
+ endsgent ();
+#endif /* NDBM */
+#endif /* SHADOWGRP */
+}
+
+/*
+ * find_new_uid - find the next available UID
+ *
+ * find_new_uid() locates the next highest unused UID in the password
+ * file, or checks the given user ID against the existing ones for
+ * uniqueness.
+ */
+
+static void
+find_new_uid(void)
+{
+ const struct passwd *pwd;
+ uid_t uid_min, uid_max;
+
+ uid_min = getdef_num("UID_MIN", 100);
+ uid_max = getdef_num("UID_MAX", 60000);
+
+ /*
+ * Start with some UID value if the user didn't provide us with
+ * one already.
+ */
+
+ if (! uflg)
+ user_id = uid_min;
+
+ /*
+ * Search the entire password file, either looking for this
+ * UID (if the user specified one with -u) or looking for the
+ * largest unused value.
+ */
+
+#ifdef NO_GETPWENT
+ pw_rewind();
+ while ((pwd = pw_next())) {
+#else /* using getpwent() we can check against NIS users etc. */
+ setpwent();
+ while ((pwd = getpwent())) {
+#endif
+ if (strcmp(user_name, pwd->pw_name) == 0) {
+ fprintf(stderr, _("%s: name %s is not unique\n"),
+ Prog, user_name);
+ exit(E_NAME_IN_USE);
+ }
+ if (uflg && user_id == pwd->pw_uid) {
+ fprintf(stderr, _("%s: uid %d is not unique\n"),
+ Prog, (int) user_id);
+ exit(E_UID_IN_USE);
+ }
+ if (! uflg && pwd->pw_uid >= user_id) {
+ if (pwd->pw_uid > uid_max)
+ continue;
+ user_id = pwd->pw_uid + 1;
+ }
+ }
+ /*
+ * If a user with uid equal to UID_MAX exists, the above algorithm
+ * will give us UID_MAX+1 even if not unique. Search for the first
+ * free uid starting with UID_MIN (it's O(n*n) but can be avoided
+ * by not having users with uid equal to UID_MAX). --marekm
+ */
+ if (!uflg && user_id == uid_max + 1) {
+ for (user_id = uid_min; user_id < uid_max; user_id++) {
+#ifdef NO_GETPWENT
+ pw_rewind();
+ while ((pwd = pw_next()) && pwd->pw_uid != user_id)
+ ;
+ if (!pwd)
+ break;
+#else
+ if (!getpwuid(user_id))
+ break;
+#endif
+ }
+ if (user_id == uid_max) {
+ fprintf(stderr, _("%s: can't get unique uid\n"),
+ Prog);
+ fail_exit(E_UID_IN_USE);
+ }
+ }
+}
+
+#ifdef AUTH_METHODS
+/*
+ * convert_auth - convert the argument list to a authentication list
+ */
+
+static void
+convert_auth(char *auths, const char *list)
+{
+ char *cp, *end;
+ char buf[257];
+
+ /*
+ * Copy each method. DEFAULT is replaced by an encrypted string
+ * if one can be found in the current authentication list.
+ */
+
+ strcpy(buf, list);
+ auths[0] = '\0';
+ for (cp = buf; cp; cp = end) {
+ if (auths[0])
+ strcat(auths, ";");
+
+ if ((end = strchr(cp, ',')))
+ *end++ = '\0';
+
+ if (strcmp(cp, "DEFAULT") == 0) {
+ strcat(auths, user_pass);
+ } else {
+ strcat(auths, "@");
+ strcat(auths, cp);
+ }
+ }
+}
+
+/*
+ * valid_auth - check authentication list for validity
+ */
+
+static int
+valid_auth(const char *methods)
+{
+ char *cp, *end;
+ char buf[257];
+ int default_cnt = 0;
+
+ /*
+ * Cursory checks, length and illegal characters
+ */
+
+ if ((int) strlen (methods) > 256)
+ return 0;
+
+ if (! VALID (methods))
+ return 0;
+
+ /*
+ * Pick each method apart and check it.
+ */
+
+ strcpy (buf, methods);
+ for (cp = buf;cp;cp = end) {
+ if ((end = strchr (cp, ',')))
+ *end++ = '\0';
+
+ if (strcmp (cp, "DEFAULT") == 0) {
+ if (default_cnt++ > 0)
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif /* AUTH_METHODS */
+
+/*
+ * process_flags - perform command line argument setting
+ *
+ * process_flags() interprets the command line arguments and sets
+ * the values that the user will be created with accordingly. The
+ * values are checked for sanity.
+ */
+
+static void
+process_flags(int argc, char **argv)
+{
+ const struct group *grp;
+ int anyflag = 0;
+ int arg;
+ char *cp;
+
+#ifdef SHADOWPWD
+#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:O:M"
+#else
+#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:O:M"
+#endif
+ while ((arg = getopt(argc, argv, FLAGS)) != EOF) {
+#undef FLAGS
+ switch (arg) {
+#ifdef AUTH_METHODS
+ case 'A':
+ if (! valid_auth (optarg)) {
+ fprintf(stderr,
+ _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ auth_arg = optarg;
+ Aflg++;
+ break;
+#endif
+ case 'b':
+ if (!Dflg)
+ usage ();
+
+ if (!VALID(optarg) || optarg[0] != '/') {
+ fprintf(stderr,
+ _("%s: invalid base directory `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ def_home = optarg;
+ bflg++;
+ break;
+ case 'c':
+ if (!VALID(optarg)) {
+ fprintf(stderr,
+ _("%s: invalid comment `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_comment = optarg;
+ cflg++;
+ break;
+ case 'd':
+ if (!VALID(optarg) || optarg[0] != '/') {
+ fprintf(stderr,
+ _("%s: invalid home directory `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_home = optarg;
+ dflg++;
+ break;
+ case 'D':
+ if (anyflag)
+ usage();
+ Dflg++;
+ break;
+#ifdef SHADOWPWD
+ case 'e':
+ if (*optarg) {
+ user_expire = strtoday(optarg);
+ if (user_expire == -1) {
+ fprintf(stderr,
+ _("%s: invalid date `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ } else
+ user_expire = -1;
+
+ /*
+ * -e "" is allowed - it's a no-op without /etc/shadow
+ */
+ if (*optarg && !is_shadow_pwd) {
+ fprintf(stderr,
+ _("%s: shadow passwords required for -e\n"),
+ Prog);
+ exit(E_USAGE);
+ }
+ if (Dflg)
+ def_expire = optarg;
+ eflg++;
+ break;
+ case 'f':
+ def_inactive = get_number(optarg);
+ /*
+ * -f -1 is allowed - it's a no-op without /etc/shadow
+ */
+ if (def_inactive != -1 && !is_shadow_pwd) {
+ fprintf(stderr,
+ _("%s: shadow passwords required for -f\n"),
+ Prog);
+ exit(E_USAGE);
+ }
+ fflg++;
+ break;
+#endif
+ case 'g':
+ grp = getgr_nam_gid(optarg);
+ if (!grp) {
+ fprintf(stderr, _("%s: unknown group %s\n"),
+ Prog, optarg);
+ exit(E_NOTFOUND);
+ }
+ if (Dflg) {
+ def_group = grp->gr_gid;
+ def_gname = optarg;
+ } else {
+ user_gid = grp->gr_gid;
+ }
+ gflg++;
+ break;
+ case 'G':
+ if (get_groups(optarg))
+ exit(E_NOTFOUND);
+ if (user_groups[0])
+ do_grp_update++;
+ Gflg++;
+ break;
+ case 'k':
+ def_template = optarg;
+ kflg++;
+ break;
+ case 'm':
+ mflg++;
+ break;
+ case 'M':
+ /*
+ * don't create home dir - this is the default,
+ * ignored for RedHat/PLD adduser compatibility.
+ */
+ break;
+ case 'o':
+ oflg++;
+ break;
+ case 'O':
+ /*
+ * override login.defs defaults (-O name=value)
+ * example: -O UID_MIN=100 -O UID_MAX=499
+ * note: -O UID_MIN=10,UID_MAX=499 doesn't work yet
+ */
+ cp = strchr(optarg, '=');
+ if (!cp) {
+ fprintf(stderr,
+ _("%s: -O requires NAME=VALUE\n"),
+ Prog);
+ exit(E_BAD_ARG);
+ }
+ /* terminate name, point to value */
+ *cp++ = '\0';
+ if (putdef_str(optarg, cp) < 0)
+ exit(E_BAD_ARG);
+ break;
+ case 'p': /* set encrypted password */
+ if (!VALID(optarg)) {
+ fprintf(stderr, _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_pass = optarg;
+ break;
+ case 's':
+ if (!VALID(optarg) || (optarg[0] &&
+ (optarg[0] != '/' && optarg[0] != '*'))) {
+ fprintf(stderr, _("%s: invalid shell `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_shell = optarg;
+ def_shell = optarg;
+ sflg++;
+ break;
+ case 'u':
+ user_id = get_number(optarg);
+ uflg++;
+ break;
+ default:
+ usage();
+ }
+ anyflag++;
+ }
+
+ /*
+ * Certain options are only valid in combination with others.
+ * Check it here so that they can be specified in any order.
+ */
+ if ((oflg && !uflg) || (kflg && !mflg))
+ usage();
+
+ /*
+ * Either -D or username is required. Defaults can be set with -D
+ * for the -b, -e, -f, -g, -s options only.
+ */
+ if (Dflg) {
+ if (optind != argc)
+ usage();
+
+ if (uflg || oflg || Gflg || dflg || cflg || mflg)
+ usage();
+ } else {
+ if (optind != argc - 1)
+ usage();
+
+ user_name = argv[optind];
+ if (!check_user_name(user_name)) {
+ fprintf(stderr, _("%s: invalid user name `%s'\n"),
+ Prog, user_name);
+ exit(E_BAD_ARG);
+ }
+ if (!dflg) {
+ char *uh;
+
+ uh = xmalloc(strlen(def_home) + strlen(user_name) + 2);
+ sprintf(uh, "%s/%s", def_home, user_name);
+ user_home = uh;
+ }
+ }
+
+#ifdef SHADOWPWD
+ if (!eflg)
+ user_expire = strtoday(def_expire);
+#endif
+
+ if (!gflg)
+ user_gid = def_group;
+
+ if (!sflg)
+ user_shell = def_shell;
+}
+
+/*
+ * close_files - close all of the files that were opened
+ *
+ * close_files() closes all of the files that were opened for this
+ * new user. This causes any modified entries to be written out.
+ */
+
+static void
+close_files(void)
+{
+ if (!pw_close()) {
+ fprintf(stderr, _("%s: cannot rewrite password file\n"), Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && !spw_close()) {
+ fprintf(stderr, _("%s: cannot rewrite shadow password file\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#endif
+ if (do_grp_update) {
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ gr_unlock();
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_close()) {
+ fprintf (stderr,
+ _("%s: cannot rewrite shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp)
+ sgr_unlock();
+#endif
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ spw_unlock();
+#endif
+ pw_unlock();
+}
+
+/*
+ * open_files - lock and open the password files
+ *
+ * open_files() opens the two password files.
+ */
+
+static void
+open_files(void)
+{
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: unable to lock password file\n"), Prog);
+ exit(E_PW_UPDATE);
+ }
+ if (!pw_open(O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open password file\n"), Prog);
+ pw_unlock();
+ exit(E_PW_UPDATE);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && !spw_lock()) {
+ fprintf(stderr, _("%s: cannot lock shadow password file\n"),
+ Prog);
+ pw_unlock();
+ exit(E_PW_UPDATE);
+ }
+ if (is_shadow_pwd && !spw_open(O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open shadow password file\n"),
+ Prog);
+ spw_unlock();
+ pw_unlock();
+ exit(E_PW_UPDATE);
+ }
+#endif
+}
+
+
+static void
+faillog_reset(uid_t uid)
+{
+ struct faillog fl;
+ int fd;
+
+ fd = open(FAILLOG_FILE, O_RDWR);
+ if (fd >= 0) {
+ memzero(&fl, sizeof(fl));
+ lseek(fd, (off_t) sizeof(fl) * uid, SEEK_SET);
+ write(fd, &fl, sizeof(fl));
+ close(fd);
+ }
+}
+
+static void
+lastlog_reset(uid_t uid)
+{
+ struct lastlog ll;
+ int fd;
+
+ fd = open(LASTLOG_FILE, O_RDWR);
+ if (fd >= 0) {
+ memzero(&ll, sizeof(ll));
+ lseek(fd, (off_t) sizeof(ll) * uid, SEEK_SET);
+ write(fd, &ll, sizeof(ll));
+ close(fd);
+ }
+}
+
+/*
+ * usr_update - create the user entries
+ *
+ * usr_update() creates the password file entries for this user
+ * and will update the group entries if required.
+ */
+
+static void
+usr_update(void)
+{
+ struct passwd pwent;
+#ifdef SHADOWPWD
+ struct spwd spent;
+#endif
+
+ if (! oflg)
+ find_new_uid ();
+
+#ifdef AUTH_METHODS
+ if (Aflg) {
+ convert_auth(user_auth, auth_arg);
+ user_pass = user_auth;
+ }
+#endif
+
+ /*
+ * Fill in the password structure with any new fields, making
+ * copies of strings.
+ */
+
+ new_pwent (&pwent);
+#ifdef SHADOWPWD
+ new_spent (&spent);
+#endif
+
+ /*
+ * Create a syslog entry. We need to do this now in case anything
+ * happens so we know what we were trying to accomplish.
+ */
+
+#ifdef AUTH_METHODS
+ SYSLOG((LOG_INFO,
+ "new user: name=%s, uid=%d, gid=%d, home=%s, shell=%s, auth=%s\n",
+ user_name, user_id, user_gid, user_home, user_shell,
+ Aflg ? auth_arg : "DEFAULT"));
+#else
+ SYSLOG((LOG_INFO,
+ "new user: name=%s, uid=%d, gid=%d, home=%s, shell=%s\n",
+ user_name, user_id, user_gid, user_home, user_shell));
+#endif
+
+#ifdef AUTH_METHODS
+ /*
+ * Attempt to add the new user to any authentication programs
+ * which have been requested. Since this is more likely to fail
+ * than the update of the password file, we do this first.
+ */
+
+ if (Aflg && pw_auth(user_auth, pwent.pw_name, PW_ADD, (char *) 0)) {
+ fprintf(stderr, _("%s: error adding authentication method\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE); /* XXX */
+ }
+#endif /* AUTH_METHODS */
+
+ /*
+ * Initialize faillog and lastlog entries for this UID in case
+ * it belongs to a previously deleted user. We do it only if
+ * no user with this UID exists yet (entries for shared UIDs
+ * are left unchanged). --marekm
+ */
+
+ if (!getpwuid(user_id)) {
+ faillog_reset(user_id);
+ lastlog_reset(user_id);
+ }
+
+ /*
+ * Put the new (struct passwd) in the table.
+ */
+
+ if (! pw_update (&pwent)) {
+ fprintf(stderr, _("%s: error adding new password entry\n"),
+ Prog);
+ exit(E_PW_UPDATE);
+ }
+
+#ifdef NDBM
+ /*
+ * Update the DBM files. This creates the user before the flat
+ * files are updated. This is safe before the password field is
+ * either locked, or set to a valid authentication string.
+ */
+
+ if (pw_dbm_present()) {
+ if (!pw_dbm_update(&pwent)) {
+ fprintf(stderr,
+ _("%s: error updating password dbm entry\n"),
+ Prog);
+ exit(E_PW_UPDATE);
+ } else
+ pw_dbm_added = 1;
+ }
+ endpwent();
+#endif
+
+#ifdef SHADOWPWD
+ /*
+ * Put the new (struct spwd) in the table.
+ */
+
+ if (is_shadow_pwd && !spw_update(&spent)) {
+ fprintf(stderr,
+ _("%s: error adding new shadow password entry\n"),
+ Prog);
+ exit(E_PW_UPDATE);
+ }
+
+#ifdef NDBM
+ /*
+ * Update the DBM files for the shadow password. This entry is
+ * output before the entry in the flat file, but this is safe as
+ * the password is locked or the authentication string has the
+ * proper values.
+ */
+
+ if (is_shadow_pwd && sp_dbm_present()) {
+ if (!sp_dbm_update(&spent)) {
+ fprintf(stderr,
+ _("%s: error updating shadow passwd dbm entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ } else
+ sp_dbm_added++;
+ endspent();
+ }
+#endif
+#endif /* SHADOWPWD */
+
+ /*
+ * Do any group file updates for this user.
+ */
+
+ if (do_grp_update)
+ grp_update();
+}
+
+/*
+ * create_home - create the user's home directory
+ *
+ * create_home() creates the user's home directory if it does not
+ * already exist. It will be created mode 755 owned by the user
+ * with the user's default group.
+ */
+
+static void
+create_home(void)
+{
+ if (access(user_home, F_OK)) {
+ /* XXX - create missing parent directories. --marekm */
+ if (mkdir (user_home, 0)) {
+ fprintf(stderr, _("%s: cannot create directory %s\n"),
+ Prog, user_home);
+ fail_exit(E_HOMEDIR);
+ }
+ chown (user_home, user_id, user_gid);
+#if 1
+ chmod(user_home, 0777 & ~getdef_num("UMASK", 077));
+#else
+ chmod (user_home, 0755);
+#endif
+ home_added++;
+ }
+}
+
+/*
+ * main - useradd command
+ */
+
+int
+main(int argc, char **argv)
+{
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+#ifdef SHADOWPWD
+ is_shadow_pwd = spw_file_present();
+#endif
+#ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present();
+#endif
+
+ /*
+ * The open routines for the NDBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
+
+#ifdef NDBM
+ pw_dbm_mode = O_RDWR;
+#ifdef SHADOWPWD
+ sp_dbm_mode = O_RDWR;
+#endif
+ gr_dbm_mode = O_RDWR;
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif
+#endif
+ get_defaults();
+
+ process_flags(argc, argv);
+
+ /*
+ * See if we are messing with the defaults file, or creating
+ * a new user.
+ */
+
+ if (Dflg) {
+ if (gflg || bflg || fflg || eflg || sflg)
+ exit (set_defaults () ? 1:0);
+
+ show_defaults();
+ exit(E_SUCCESS);
+ }
+
+ /*
+ * Start with a quick check to see if the user exists.
+ */
+
+ if (getpwnam(user_name)) {
+ fprintf(stderr, _("%s: user %s exists\n"), Prog, user_name);
+ exit(E_NAME_IN_USE);
+ }
+
+ /*
+ * Do the hard stuff - open the files, create the user entries,
+ * create the home directory, then close and update the files.
+ */
+
+ open_files ();
+
+ usr_update ();
+
+ if (mflg) {
+ create_home ();
+ copy_tree (def_template, user_home, user_id, user_gid);
+ } else if (getdef_str("CREATE_HOME")) {
+ /*
+ * RedHat added the CREATE_HOME option in login.defs in their
+ * version of shadow-utils (which makes -m the default, with
+ * new -M option to turn it off). Unfortunately, this
+ * changes the way useradd works (it can be run by scripts
+ * expecting some standard behaviour), compared to other
+ * Unices and other Linux distributions, and also adds a lot
+ * of confusion :-(.
+ * So we now recognize CREATE_HOME and give a warning here
+ * (better than "configuration error ... notify administrator"
+ * errors in every program that reads /etc/login.defs). -MM
+ */
+ fprintf(stderr,
+ _("%s: warning: CREATE_HOME not supported, please use -m instead.\n"),
+ Prog);
+ }
+
+ close_files ();
+
+ exit(E_SUCCESS);
+ /*NOTREACHED*/
+}
diff --git a/current/src/userdel.c b/current/src/userdel.c
new file mode 100644
index 00000000..7637a4f1
--- /dev/null
+++ b/current/src/userdel.c
@@ -0,0 +1,846 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: userdel.c,v 1.17 2000/09/02 18:40:44 marekm Exp $")
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include "getdef.h"
+#include "pwauth.h"
+
+/*
+ * exit status values
+ */
+#define E_SUCCESS 0
+#define E_PW_UPDATE 1 /* can't update password file */
+#define E_USAGE 2 /* bad command syntax */
+#define E_NOTFOUND 6 /* specified user doesn't exist */
+#define E_USER_BUSY 8 /* user currently logged in */
+#define E_GRP_UPDATE 10 /* can't update group file */
+#define E_HOMEDIR 12 /* can't remove home directory */
+
+static char *user_name;
+static uid_t user_id;
+static char *user_home;
+
+static char *Prog;
+static int fflg = 0, rflg = 0;
+
+#ifdef NDBM
+extern int pw_dbm_mode;
+#ifdef SHADOWPWD
+extern int sp_dbm_mode;
+#endif
+extern int gr_dbm_mode;
+#ifdef SHADOWGRP
+extern int sg_dbm_mode;
+#endif
+#endif
+
+#include "groupio.h"
+#include "pwio.h"
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+
+#ifdef HAVE_TCFS
+#include <tcfslib.h>
+#include "tcfsio.h"
+#endif
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+#endif
+
+#ifdef SHADOWPWD
+static int is_shadow_pwd;
+#endif
+#ifdef SHADOWGRP
+static int is_shadow_grp;
+#endif
+
+extern int optind;
+
+/* local function prototypes */
+static void usage(void);
+static void update_groups(void);
+static void close_files(void);
+static void fail_exit(int);
+static void open_files(void);
+static void update_user(void);
+static void user_busy(const char *, uid_t);
+static void user_cancel(const char *);
+#ifdef EXTRA_CHECK_HOME_DIR
+static int path_prefix(const char *, const char *);
+#endif
+static int is_owner(uid_t, const char *);
+#ifndef NO_REMOVE_MAILBOX
+static void remove_mailbox(void);
+#endif
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("usage: %s [-r] name\n"), Prog);
+ exit(E_USAGE);
+}
+
+/*
+ * update_groups - delete user from secondary group set
+ *
+ * update_groups() takes the user name that was given and searches
+ * the group files for membership in any group.
+ *
+ * we also check to see if they have any groups they own (the same
+ * name is their user name) and delete them too (only if USERGROUPS_ENAB
+ * is enabled).
+ */
+
+static void
+update_groups(void)
+{
+ const struct group *grp;
+ struct group *ngrp;
+#ifdef SHADOWGRP
+ const struct sgrp *sgrp;
+ struct sgrp *nsgrp;
+#endif /* SHADOWGRP */
+
+ /*
+ * Scan through the entire group file looking for the groups that
+ * the user is a member of.
+ */
+
+ for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
+
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+
+ if (!is_on_list(grp->gr_mem, user_name))
+ continue;
+
+ /*
+ * Delete the username from the list of group members and
+ * update the group entry to reflect the change.
+ */
+
+ ngrp = __gr_dup(grp);
+ if (!ngrp) {
+ exit(13); /* XXX */
+ }
+ ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
+ if (!gr_update(ngrp))
+ fprintf(stderr, _("%s: error updating group entry\n"),
+ Prog);
+
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+#ifdef NDBM
+ if (!gr_dbm_update(ngrp))
+ fprintf(stderr,
+ _("%s: cannot update dbm group entry\n"),
+ Prog);
+#endif /* NDBM */
+ SYSLOG((LOG_INFO, "delete `%s' from group `%s'\n",
+ user_name, ngrp->gr_name));
+ }
+#ifdef NDBM
+ endgrent();
+#endif
+ /*
+ * we've removed their name from all the groups above, so
+ * now if they have a group with the same name as their
+ * user name, with no members, we delete it.
+ */
+
+ grp = getgrnam(user_name);
+ if (grp && getdef_bool("USERGROUPS_ENAB") && (grp->gr_mem[0] == NULL)) {
+
+ gr_remove(grp->gr_name);
+
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+#ifdef NDBM
+ if (!gr_dbm_remove(grp))
+ fprintf(stderr,
+ _("%s: cannot remove dbm group entry\n"),
+ Prog);
+#endif
+ SYSLOG((LOG_INFO, "removed group `%s' owned by `%s'\n",
+ grp->gr_name, user_name));
+ }
+#ifdef NDBM
+ endgrent ();
+#endif
+#ifdef SHADOWGRP
+ if (!is_shadow_grp)
+ return;
+
+ /*
+ * Scan through the entire shadow group file looking for the groups
+ * that the user is a member of. Both the administrative list and
+ * the ordinary membership list is checked.
+ */
+
+ for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
+ int was_member, was_admin;
+
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+
+ was_member = is_on_list(sgrp->sg_mem, user_name);
+ was_admin = is_on_list(sgrp->sg_adm, user_name);
+
+ if (!was_member && !was_admin)
+ continue;
+
+ nsgrp = __sgr_dup(sgrp);
+ if (!nsgrp) {
+ exit(13); /* XXX */
+ }
+
+ if (was_member)
+ nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
+
+ if (was_admin)
+ nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
+
+ if (!sgr_update(nsgrp))
+ fprintf(stderr, _("%s: error updating group entry\n"),
+ Prog);
+#ifdef NDBM
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+
+ if (!sg_dbm_update(nsgrp))
+ fprintf(stderr,
+ _("%s: cannot update dbm group entry\n"),
+ Prog);
+#endif /* NDBM */
+ SYSLOG((LOG_INFO, "delete `%s' from shadow group `%s'\n",
+ user_name, nsgrp->sg_name));
+ }
+#ifdef NDBM
+ endsgent ();
+#endif /* NDBM */
+#endif /* SHADOWGRP */
+}
+
+/*
+ * close_files - close all of the files that were opened
+ *
+ * close_files() closes all of the files that were opened for this
+ * new user. This causes any modified entries to be written out.
+ */
+
+static void
+close_files(void)
+{
+ if (!pw_close())
+ fprintf(stderr, _("%s: cannot rewrite password file\n"), Prog);
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && !spw_close())
+ fprintf(stderr, _("%s: cannot rewrite shadow password file\n"),
+ Prog);
+#endif
+#ifdef HAVE_TCFS
+ if (!tcfs_close())
+ fprintf(stderr, _("%s: cannot rewrite TCFS key file\n"), Prog);
+#endif
+ if (! gr_close ())
+ fprintf(stderr, _("%s: cannot rewrite group file\n"),
+ Prog);
+
+ (void) gr_unlock ();
+#ifdef SHADOWGRP
+ if (is_shadow_grp && !sgr_close())
+ fprintf(stderr, _("%s: cannot rewrite shadow group file\n"),
+ Prog);
+
+ if (is_shadow_grp)
+ (void) sgr_unlock();
+#endif
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ (void) spw_unlock();
+#endif
+#ifdef HAVE_TCFS
+ (void) tcfs_unlock();
+#endif
+ (void) pw_unlock();
+}
+
+/*
+ * fail_exit - exit with a failure code after unlocking the files
+ */
+
+static void
+fail_exit(int code)
+{
+ (void) pw_unlock ();
+ (void) gr_unlock ();
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ spw_unlock ();
+#endif
+#ifdef SHADOWGRP
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif
+#ifdef HAVE_TCFS
+ (void) tcfs_unlock ();
+#endif
+
+ exit(code);
+}
+
+/*
+ * open_files - lock and open the password files
+ *
+ * open_files() opens the two password files.
+ */
+
+static void
+open_files(void)
+{
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: unable to lock password file\n"), Prog);
+ exit(E_PW_UPDATE);
+ }
+ if (! pw_open (O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open password file\n"), Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && ! spw_lock ()) {
+ fprintf(stderr, _("%s: cannot lock shadow password file\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (is_shadow_pwd && ! spw_open (O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open shadow password file\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#endif
+#ifdef HAVE_TCFS
+ if (!tcfs_lock()) {
+ fprintf(stderr, _("%s: cannot lock TCFS key file\n"), Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (!tcfs_open(O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open TCFS key file\n"), Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#endif
+ if (! gr_lock ()) {
+ fprintf(stderr, _("%s: unable to lock group file\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (! gr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open group file\n"), Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow_grp && ! sgr_lock ()) {
+ fprintf(stderr, _("%s: unable to lock shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+ if (is_shadow_grp && ! sgr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open shadow group file\n"),
+ Prog);
+ fail_exit(E_GRP_UPDATE);
+ }
+#endif
+}
+
+/*
+ * update_user - delete the user entries
+ *
+ * update_user() deletes the password file entries for this user
+ * and will update the group entries as required.
+ */
+
+static void
+update_user(void)
+{
+#if defined(AUTH_METHODS) || defined(NDBM)
+ struct passwd *pwd;
+#endif
+#ifdef AUTH_METHODS
+#ifdef SHADOWPWD
+ struct spwd *spwd;
+
+ if (is_shadow_pwd && (spwd = spw_locate (user_name)) &&
+ spwd->sp_pwdp[0] == '@') {
+ if (pw_auth (spwd->sp_pwdp + 1, user_name, PW_DELETE, (char *) 0)) {
+ SYSLOG((LOG_ERR,
+ "failed deleting auth `%s' for user `%s'\n",
+ spwd->sp_pwdp + 1, user_name));
+ fprintf(stderr,
+ _("%s: error deleting authentication\n"),
+ Prog);
+ } else {
+ SYSLOG((LOG_INFO,
+ "delete auth `%s' for user `%s'\n",
+ spwd->sp_pwdp + 1, user_name));
+ }
+ }
+#endif /* SHADOWPWD */
+ if ((pwd = pw_locate(user_name)) && pwd->pw_passwd[0] == '@') {
+ if (pw_auth(pwd->pw_passwd + 1, user_name, PW_DELETE, (char *) 0)) {
+ SYSLOG((LOG_ERR,
+ "failed deleting auth `%s' for user `%s'\n",
+ pwd->pw_passwd + 1, user_name));
+ fprintf(stderr,
+ _("%s: error deleting authentication\n"),
+ Prog);
+ } else {
+ SYSLOG((LOG_INFO, "delete auth `%s' for user `%s'\n",
+ pwd->pw_passwd + 1, user_name);
+ }
+ }
+#endif /* AUTH_METHODS */
+ if (!pw_remove(user_name))
+ fprintf(stderr, _("%s: error deleting password entry\n"), Prog);
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && ! spw_remove (user_name))
+ fprintf(stderr, _("%s: error deleting shadow password entry\n"),
+ Prog);
+#endif
+#ifdef HAVE_TCFS
+ if (tcfs_locate (user_name)) {
+ if (!tcfs_remove (user_name)) {
+ SYSLOG((LOG_ERR,
+ "failed deleting TCFS entry for user `%s'\n",
+ user_name));
+ fprintf(stderr, _("%s: error deleting TCFS entry\n"),
+ Prog);
+ } else {
+ SYSLOG((LOG_INFO,
+ "delete TCFS entry for user `%s'\n",
+ user_name));
+ }
+ }
+#endif /* HAVE_TCFS */
+#ifdef NDBM
+ if (pw_dbm_present()) {
+ if ((pwd = getpwnam (user_name)) && ! pw_dbm_remove (pwd))
+ fprintf(stderr,
+ _("%s: error deleting password dbm entry\n"),
+ Prog);
+ }
+
+ /*
+ * If the user's UID is a duplicate the duplicated entry needs
+ * to be updated so that a UID match can be found in the DBM
+ * files.
+ */
+
+ for (pw_rewind (), pwd = pw_next ();pwd;pwd = pw_next ()) {
+ if (pwd->pw_uid == user_id) {
+ pw_dbm_update (pwd);
+ break;
+ }
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && sp_dbm_present() && !sp_dbm_remove(user_name))
+ fprintf(stderr,
+ _("%s: error deleting shadow passwd dbm entry\n"),
+ Prog);
+
+ endspent ();
+#endif
+ endpwent ();
+#endif /* NDBM */
+ SYSLOG((LOG_INFO, "delete user `%s'\n", user_name));
+}
+
+/*
+ * user_busy - see if user is logged in.
+ *
+ * XXX - should probably check if there are any processes owned
+ * by this user. Also, I think this check should be in usermod
+ * as well (at least when changing username or uid). --marekm
+ */
+
+static void
+user_busy(const char *name, uid_t uid)
+{
+ struct utmp *utent;
+
+ /*
+ * We see if the user is logged in by looking for the user name
+ * in the utmp file.
+ */
+
+ setutent ();
+
+ while ((utent = getutent ())) {
+#ifdef USER_PROCESS
+ if (utent->ut_type != USER_PROCESS)
+ continue;
+#else
+ if (utent->ut_user[0] == '\0')
+ continue;
+#endif
+ if (strncmp(utent->ut_user, name, sizeof utent->ut_user))
+ continue;
+
+ fprintf(stderr, _("%s: user %s is currently logged in\n"),
+ Prog, name);
+ exit(E_USER_BUSY);
+ }
+}
+
+/*
+ * user_cancel - cancel cron and at jobs
+ *
+ * user_cancel removes the crontab and any at jobs for a user
+ */
+
+/*
+ * We used to have all this stuff hardcoded here, but now
+ * we just run an external script - it may need to do other
+ * things as well (like removing print jobs) and we may not
+ * want to recompile userdel too often. Below is a sample
+ * script (should work at least on Debian 1.1). --marekm
+==========
+#! /bin/sh
+
+# Check for the required argument.
+if [ $# != 1 ]; then
+ echo Usage: $0 username
+ exit 1
+fi
+
+# Remove cron jobs.
+crontab -r -u $1
+
+# Remove at jobs. XXX - will remove any jobs owned by the
+# same UID, even if it was shared by a different username.
+# at really should store the username somewhere, and atrm
+# should support an option to remove all jobs owned by the
+# specified user - for now we have to do this ugly hack...
+find /var/spool/cron/atjobs -name "[^.]*" -type f -user $1 -exec rm {} \;
+
+# Remove print jobs.
+lprm $1
+
+# All done.
+exit 0
+==========
+ */
+
+static void
+user_cancel(const char *user)
+{
+ char *cmd;
+ int pid, wpid;
+ int status;
+
+ if (!(cmd = getdef_str("USERDEL_CMD")))
+ return;
+
+ pid = fork();
+ if (pid == 0) {
+ execl(cmd, cmd, user, (char *) 0);
+ if (errno == ENOENT) {
+ perror(cmd);
+ _exit(127);
+ } else {
+ perror(cmd);
+ _exit(126);
+ }
+ } else if (pid == -1) {
+ perror("fork");
+ return;
+ }
+
+ do {
+ wpid = wait(&status);
+ } while (wpid != pid && wpid != -1);
+}
+
+#ifdef EXTRA_CHECK_HOME_DIR
+static int
+path_prefix(const char *s1, const char *s2)
+{
+ return (strncmp(s2, s1, strlen(s1)) == 0);
+}
+#endif
+
+static int
+is_owner(uid_t uid, const char *path)
+{
+ struct stat st;
+
+ if (stat(path, &st))
+ return -1;
+ return (st.st_uid == uid);
+}
+
+#ifndef NO_REMOVE_MAILBOX
+static void
+remove_mailbox(void)
+{
+ const char *maildir;
+ char mailfile[1024];
+ int i;
+
+ maildir = getdef_str("MAIL_DIR");
+#ifdef MAIL_SPOOL_DIR
+ if (!maildir && !getdef_str("MAIL_FILE"))
+ maildir = MAIL_SPOOL_DIR;
+#endif
+ if (!maildir)
+ return;
+
+ snprintf(mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
+ if (fflg) {
+ unlink(mailfile); /* always remove, ignore errors */
+ return;
+ }
+ i = is_owner(user_id, mailfile);
+ if (i == 0) {
+ fprintf(stderr,
+ _("%s: warning: %s not owned by %s, not removing\n"),
+ Prog, mailfile, user_name);
+ return;
+ } else if (i == -1)
+ return; /* mailbox doesn't exist */
+ if (unlink(mailfile)) {
+ fprintf(stderr, _("%s: warning: can't remove "), Prog);
+ perror(mailfile);
+ }
+}
+#endif
+
+/*
+ * main - userdel command
+ */
+
+int
+main(int argc, char **argv)
+{
+ struct passwd *pwd;
+ int arg;
+ int errors = 0;
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+#ifdef SHADOWPWD
+ is_shadow_pwd = spw_file_present();
+#endif
+
+#ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present();
+#endif
+
+ /*
+ * The open routines for the DBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
+
+#ifdef NDBM
+ pw_dbm_mode = O_RDWR;
+#ifdef SHADOWPWD
+ sp_dbm_mode = O_RDWR;
+#endif
+ gr_dbm_mode = O_RDWR;
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif
+#endif
+ while ((arg = getopt (argc, argv, "fr")) != EOF) {
+ switch (arg) {
+ case 'f': /* force remove even if not owned by user */
+ fflg++;
+ break;
+ case 'r': /* remove home dir and mailbox */
+ rflg++;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (optind + 1 != argc)
+ usage ();
+
+ /*
+ * Start with a quick check to see if the user exists.
+ */
+
+ user_name = argv[argc - 1];
+
+ if (! (pwd = getpwnam (user_name))) {
+ fprintf(stderr, _("%s: user %s does not exist\n"),
+ Prog, user_name);
+ exit(E_NOTFOUND);
+ }
+#ifdef USE_NIS
+
+ /*
+ * Now make sure it isn't an NIS user.
+ */
+
+ if (__ispwNIS ()) {
+ char *nis_domain;
+ char *nis_master;
+
+ fprintf(stderr, _("%s: user %s is a NIS user\n"),
+ Prog, user_name);
+
+ if (! yp_get_default_domain (&nis_domain) &&
+ ! yp_master (nis_domain, "passwd.byname",
+ &nis_master)) {
+ fprintf(stderr, _("%s: %s is the NIS master\n"),
+ Prog, nis_master);
+ }
+ exit(E_NOTFOUND);
+ }
+#endif
+ user_id = pwd->pw_uid;
+ user_home = xstrdup(pwd->pw_dir);
+
+ /*
+ * Check to make certain the user isn't logged in.
+ */
+
+ user_busy (user_name, user_id);
+
+ /*
+ * Do the hard stuff - open the files, create the user entries,
+ * create the home directory, then close and update the files.
+ */
+
+ open_files ();
+
+ update_user ();
+ update_groups ();
+
+#ifndef NO_REMOVE_MAILBOX
+ if (rflg)
+ remove_mailbox();
+#endif
+
+ if (rflg && !fflg && !is_owner(user_id, user_home)) {
+ fprintf(stderr, _("%s: %s not owned by %s, not removing\n"),
+ Prog, user_home, user_name);
+ rflg = 0;
+ errors++;
+ }
+
+/* This may be slow, the above should be good enough. */
+#ifdef EXTRA_CHECK_HOME_DIR
+ if (rflg && !fflg) {
+ /*
+ * For safety, refuse to remove the home directory
+ * if it would result in removing some other user's
+ * home directory. Still not perfect so be careful,
+ * but should prevent accidents if someone has /home
+ * or / as home directory... --marekm
+ */
+ setpwent();
+ while ((pwd = getpwent())) {
+ if (strcmp(pwd->pw_name, user_name) == 0)
+ continue;
+
+ if (path_prefix(user_home, pwd->pw_dir)) {
+ fprintf(stderr,
+ _("%s: not removing directory %s (would remove home of user %s)\n"),
+ Prog, user_home, pwd->pw_name);
+
+ rflg = 0;
+ errors++;
+ break;
+ }
+ }
+ }
+#endif
+
+ if (rflg) {
+ if (remove_tree(user_home) || rmdir(user_home)) {
+ fprintf(stderr, _("%s: error removing directory %s\n"),
+ Prog, user_home);
+
+ errors++;
+ }
+ }
+
+ /*
+ * Cancel any crontabs or at jobs. Have to do this before we
+ * remove the entry from /etc/passwd.
+ */
+
+ user_cancel(user_name);
+
+ close_files ();
+
+ exit(errors ? E_HOMEDIR : E_SUCCESS);
+ /*NOTREACHED*/
+}
diff --git a/current/src/usermod.c b/current/src/usermod.c
new file mode 100644
index 00000000..447e3c64
--- /dev/null
+++ b/current/src/usermod.c
@@ -0,0 +1,1705 @@
+/*
+ * Copyright 1991 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: usermod.c,v 1.19 2000/09/02 18:40:44 marekm Exp $")
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include "prototypes.h"
+#include "defines.h"
+#include "chkname.h"
+#include "faillog.h"
+#if HAVE_LASTLOG_H
+#include <lastlog.h>
+#else
+#include "lastlog_.h"
+#endif
+#include "pwauth.h"
+#include "getdef.h"
+
+/*
+ * exit status values
+ * for E_GRP_UPDATE and E_NOSPACE (not used yet), other update requests
+ * will be implemented (as documented in the Solaris 2.x man page).
+ */
+#define E_SUCCESS 0 /* success */
+#define E_PW_UPDATE 1 /* can't update password file */
+#define E_USAGE 2 /* invalid command syntax */
+#define E_BAD_ARG 3 /* invalid argument to option */
+#define E_UID_IN_USE 4 /* uid already in use (and no -o) */
+/* #define E_BAD_PWFILE 5 */ /* passwd file contains errors */
+#define E_NOTFOUND 6 /* specified user/group doesn't exist */
+#define E_USER_BUSY 8 /* user to modify is logged in */
+#define E_NAME_IN_USE 9 /* username already in use */
+#define E_GRP_UPDATE 10 /* can't update group file */
+/* #define E_NOSPACE 11 */ /* insufficient space to move home dir */
+#define E_HOMEDIR 12 /* unable to complete home dir move */
+
+#define VALID(s) (strcspn (s, ":\n") == strlen (s))
+
+static char *user_name;
+static char *user_newname;
+static char *user_pass;
+static uid_t user_id;
+static uid_t user_newid;
+static gid_t user_gid;
+static gid_t user_newgid;
+static char *user_comment;
+static char *user_home;
+static char *user_newhome;
+static char *user_shell;
+#ifdef SHADOWPWD
+static long user_expire;
+static long user_inactive;
+#endif
+static char *user_groups[NGROUPS_MAX+1]; /* NULL-terminated list */
+
+static char *Prog;
+
+#ifdef AUTH_METHODS
+static char *auth_arg;
+static char user_auth[BUFSIZ];
+static int Aflg = 0; /* specify user defined authentication method */
+#else
+#define Aflg 0
+#endif
+
+static int
+ uflg = 0, /* specify new user ID */
+ oflg = 0, /* permit non-unique user ID to be specified with -u */
+ gflg = 0, /* new primary group ID */
+ Gflg = 0, /* new secondary group set */
+ dflg = 0, /* new home directory */
+ sflg = 0, /* new shell program */
+ cflg = 0, /* new comment (GECOS) field */
+ mflg = 0, /* create user's home directory if it doesn't exist */
+#ifdef SHADOWPWD
+ fflg = 0, /* days until account with expired password is locked */
+ eflg = 0, /* days since 1970-01-01 when account becomes expired */
+#endif
+ Lflg = 0, /* lock the password */
+ Uflg = 0, /* unlock the password */
+ pflg = 0, /* new encrypted password */
+ lflg = 0; /* new user name */
+
+#ifdef NDBM
+extern int pw_dbm_mode;
+#ifdef SHADOWPWD
+extern int sp_dbm_mode;
+#endif
+extern int gr_dbm_mode;
+#ifdef SHADOWGRP
+extern int sg_dbm_mode;
+#endif
+#endif
+
+#ifdef SHADOWPWD
+static int is_shadow_pwd;
+#endif
+#ifdef SHADOWGRP
+static int is_shadow_grp;
+#endif
+
+#include "groupio.h"
+
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+#endif
+
+#include "pwio.h"
+
+#ifdef SHADOWPWD
+#include "shadowio.h"
+#endif
+
+extern char *optarg;
+extern int optind;
+
+/* local function prototypes */
+static int get_groups(char *);
+static void usage(void);
+static void new_pwent(struct passwd *);
+#ifdef SHADOWPWD
+static void new_spent(struct spwd *);
+#endif
+static void fail_exit(int);
+static int update_group(void);
+#ifdef SHADOWGRP
+static int update_gshadow(void);
+#endif
+static int grp_update(void);
+#ifdef AUTH_METHODS
+static char *get_password(const char *);
+static void split_auths(char *, char **);
+static void update_auths(const char *, const char *, char *);
+static void add_auths(const char *, const char *, char *);
+static void delete_auths(const char *, const char *, char *);
+static void convert_auth(char *, const char *, const char *);
+static int valid_auth(const char *);
+#endif
+static long get_number(const char *);
+static void process_flags(int, char **);
+static void close_files(void);
+static void open_files(void);
+static void usr_update(void);
+static void move_home(void);
+static void update_files(void);
+#ifndef NO_MOVE_MAILBOX
+static void move_mailbox(void);
+#endif
+
+/* Had to move this over from useradd.c since we have groups named
+ * "56k-family"... ergh.
+ * --Pac. */
+static struct group *
+getgr_nam_gid(const char *name)
+{
+ gid_t gid;
+ char *ep;
+
+ gid = strtol(name, &ep, 10);
+ if (*name != '\0' && *ep == '\0') /* valid numeric gid */
+ return getgrgid(gid);
+
+ return getgrnam(name);
+}
+
+
+/*
+ * get_groups - convert a list of group names to an array of group IDs
+ *
+ * get_groups() takes a comma-separated list of group names and
+ * converts it to a NULL-terminated array. Any unknown group
+ * names are reported as errors.
+ */
+
+static int
+get_groups(char *list)
+{
+ char *cp;
+ const struct group *grp;
+ int errors = 0;
+ int ngroups = 0;
+
+ /*
+ * Initialize the list to be empty
+ */
+
+ user_groups[0] = (char *) 0;
+
+ if (! *list)
+ return 0;
+
+ /*
+ * So long as there is some data to be converted, strip off
+ * each name and look it up. A mix of numerical and string
+ * values for group identifiers is permitted.
+ */
+
+ do {
+ /*
+ * Strip off a single name from the list
+ */
+ if ((cp = strchr (list, ',')))
+ *cp++ = '\0';
+
+ /*
+ * Names starting with digits are treated as numerical
+ * GID values, otherwise the string is looked up as is.
+ */
+ grp = getgr_nam_gid(list);
+
+ /*
+ * There must be a match, either by GID value or by
+ * string name.
+ */
+ if (!grp) {
+ fprintf(stderr, _("%s: unknown group %s\n"),
+ Prog, list);
+ errors++;
+ }
+ list = cp;
+
+ /*
+ * If the group doesn't exist, don't dump core...
+ * Instead, try the next one. --marekm
+ */
+ if (! grp)
+ continue;
+
+#ifdef USE_NIS
+ /*
+ * Don't add this group if they are an NIS group. Tell
+ * the user to go to the server for this group.
+ */
+
+ if (__isgrNIS ()) {
+ fprintf(stderr, _("%s: group `%s' is a NIS group.\n"),
+ Prog, grp->gr_name);
+ continue;
+ }
+#endif
+
+ if (ngroups == NGROUPS_MAX) {
+ fprintf(stderr,
+ _("%s: too many groups specified (max %d).\n"),
+ Prog, ngroups);
+ break;
+ }
+
+ /*
+ * Add the group name to the user's list of groups.
+ */
+
+ user_groups[ngroups++] = xstrdup(grp->gr_name);
+ } while (list);
+
+ user_groups[ngroups] = (char *) 0;
+
+ /*
+ * Any errors in finding group names are fatal
+ */
+
+ if (errors)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * usage - display usage message and exit
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ _("usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"),
+ Prog);
+ fprintf(stderr,
+ _("\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"));
+ fprintf(stderr, "\t\t");
+#ifdef SHADOWPWD
+ fprintf(stderr, _("[-f inactive] [-e expire ] "));
+#endif
+#ifdef AUTH_METHODS
+ fprintf(stderr, _("[-A {DEFAULT|program},... ] "));
+#endif
+ fprintf(stderr, _("[-p passwd] [-L|-U] name\n"));
+ exit(E_USAGE);
+}
+
+/* update encrypted password string (for both shadow and non-shadow passwords) */
+
+static char *
+new_pw_passwd(char *pw_pass, const char *pw_name)
+{
+ if (Lflg && pw_pass[0] != '!') {
+ char *buf = xmalloc(strlen(pw_pass) + 2);
+
+ SYSLOG((LOG_INFO, "lock user `%s' password\n",
+ pw_name));
+ strcpy(buf, "!");
+ strcat(buf, pw_pass);
+ pw_pass = buf;
+ } else if (Uflg && pw_pass[0] == '!') {
+ char *s;
+
+ SYSLOG((LOG_INFO, "unlock user `%s' password\n",
+ pw_name));
+ s = pw_pass;
+ while (*s) {
+ *s = *(s + 1);
+ s++;
+ }
+ } else if (pflg) {
+ SYSLOG((LOG_INFO, "change user `%s' password\n",
+ pw_name));
+ pw_pass = xstrdup(user_pass);
+ }
+ return pw_pass;
+}
+
+/*
+ * new_pwent - initialize the values in a password file entry
+ *
+ * new_pwent() takes all of the values that have been entered and
+ * fills in a (struct passwd) with them.
+ */
+
+static void
+new_pwent(struct passwd *pwent)
+{
+ if (lflg) {
+ SYSLOG((LOG_INFO, "change user name `%s' to `%s'\n",
+ pwent->pw_name, user_newname));
+ pwent->pw_name = xstrdup (user_newname);
+ }
+
+#ifdef SHADOWPWD
+ if (!is_shadow_pwd)
+#endif
+ pwent->pw_passwd = new_pw_passwd(pwent->pw_passwd, pwent->pw_name);
+
+ if (uflg) {
+ SYSLOG((LOG_INFO, "change user `%s' UID from `%d' to `%d'\n",
+ pwent->pw_name, pwent->pw_uid, user_newid));
+ pwent->pw_uid = user_newid;
+ }
+ if (gflg) {
+ SYSLOG((LOG_INFO, "change user `%s' GID from `%d' to `%d'\n",
+ pwent->pw_name, pwent->pw_gid, user_newgid));
+ pwent->pw_gid = user_newgid;
+ }
+ if (cflg)
+ pwent->pw_gecos = user_comment;
+
+ if (dflg) {
+ SYSLOG((LOG_INFO, "change user `%s' home from `%s' to `%s'\n",
+ pwent->pw_name, pwent->pw_dir, user_newhome));
+ pwent->pw_dir = user_newhome;
+ }
+ if (sflg) {
+ SYSLOG((LOG_INFO, "change user `%s' shell from `%s' to `%s'\n",
+ pwent->pw_name, pwent->pw_shell, user_shell));
+ pwent->pw_shell = user_shell;
+ }
+}
+
+#ifdef SHADOWPWD
+/*
+ * new_spent - initialize the values in a shadow password file entry
+ *
+ * new_spent() takes all of the values that have been entered and
+ * fills in a (struct spwd) with them.
+ */
+
+static void
+new_spent(struct spwd *spent)
+{
+ if (lflg)
+ spent->sp_namp = xstrdup (user_newname);
+
+ if (fflg) {
+ SYSLOG((LOG_INFO,
+ "change user `%s' inactive from `%ld' to `%ld'\n",
+ spent->sp_namp, spent->sp_inact, user_inactive));
+ spent->sp_inact = user_inactive;
+ }
+ if (eflg) {
+ /* XXX - dates might be better than numbers of days. --marekm */
+ SYSLOG((LOG_INFO,
+ "change user `%s' expiration from `%ld' to `%ld'\n",
+ spent->sp_namp, spent->sp_expire, user_expire));
+ spent->sp_expire = user_expire;
+ }
+ spent->sp_pwdp = new_pw_passwd(spent->sp_pwdp, spent->sp_namp);
+}
+#endif /* SHADOWPWD */
+
+/*
+ * fail_exit - exit with an error code after unlocking files
+ */
+
+static void
+fail_exit(int code)
+{
+ (void) gr_unlock ();
+#ifdef SHADOWGRP
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ spw_unlock ();
+#endif
+ (void) pw_unlock ();
+ exit(code);
+}
+
+
+static int
+update_group(void)
+{
+ int is_member;
+ int was_member;
+ int changed;
+ const struct group *grp;
+ struct group *ngrp;
+
+ /*
+ * Lock and open the group file. This will load all of the group
+ * entries.
+ */
+ if (! gr_lock ()) {
+ fprintf(stderr, _("%s: error locking group file\n"), Prog);
+ SYSLOG((LOG_ERR, "error locking group file"));
+ return -1;
+ }
+ if (! gr_open (O_RDWR)) {
+ fprintf(stderr, _("%s: error opening group file\n"), Prog);
+ SYSLOG((LOG_ERR, "error opening group file"));
+ gr_unlock();
+ return -1;
+ }
+
+ changed = 0;
+
+ /*
+ * Scan through the entire group file looking for the groups that
+ * the user is a member of.
+ */
+ while ((grp = gr_next())) {
+
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+ was_member = is_on_list(grp->gr_mem, user_name);
+ is_member = Gflg && is_on_list(user_groups, grp->gr_name);
+
+ if (!was_member && !is_member)
+ continue;
+
+ ngrp = __gr_dup(grp);
+ if (!ngrp) {
+ fprintf(stderr,
+ _("%s: out of memory in update_group\n"),
+ Prog);
+ gr_unlock();
+ return -1;
+ }
+
+ if (was_member && (!Gflg || is_member)) {
+ if (lflg) {
+ ngrp->gr_mem = del_list(ngrp->gr_mem,
+ user_name);
+ ngrp->gr_mem = add_list(ngrp->gr_mem,
+ user_newname);
+ changed = 1;
+ SYSLOG((LOG_INFO,
+ "change `%s' to `%s' in group `%s'\n",
+ user_name, user_newname,
+ ngrp->gr_name));
+ }
+ } else if (was_member && Gflg && !is_member) {
+ ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
+ changed = 1;
+ SYSLOG((LOG_INFO, "delete `%s' from group `%s'\n",
+ user_name, ngrp->gr_name));
+ } else if (!was_member && Gflg && is_member) {
+ ngrp->gr_mem = add_list (ngrp->gr_mem,
+ lflg ? user_newname:user_name);
+ changed = 1;
+ SYSLOG((LOG_INFO, "add `%s' to group `%s'\n",
+ lflg ? user_newname:user_name, ngrp->gr_name));
+ }
+ if (!changed)
+ continue;
+
+ changed = 0;
+ if (! gr_update (ngrp)) {
+ fprintf(stderr, _("%s: error adding new group entry\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error adding group entry"));
+ gr_unlock();
+ return -1;
+ }
+#ifdef NDBM
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+ if (! gr_dbm_update (ngrp)) {
+ fprintf(stderr,
+ _("%s: cannot add new dbm group entry\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error adding dbm group entry"));
+ gr_unlock();
+ return -1;
+ }
+#endif /* NDBM */
+ }
+#ifdef NDBM
+ endgrent ();
+#endif /* NDBM */
+ if (!gr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite group file\n"),
+ Prog);
+ gr_unlock();
+ return -1;
+ }
+ gr_unlock();
+ return 0;
+}
+
+#ifdef SHADOWGRP
+static int
+update_gshadow(void)
+{
+ int is_member;
+ int was_member;
+ int was_admin;
+ int changed;
+ const struct sgrp *sgrp;
+ struct sgrp *nsgrp;
+
+ if (!sgr_lock()) {
+ fprintf(stderr, _("%s: error locking shadow group file\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error locking shadow group file"));
+ return -1;
+ }
+ if (!sgr_open(O_RDWR)) {
+ fprintf(stderr, _("%s: error opening shadow group file\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error opening shadow group file"));
+ sgr_unlock();
+ return -1;
+ }
+
+ changed = 0;
+
+ /*
+ * Scan through the entire shadow group file looking for the groups
+ * that the user is a member of.
+ */
+ while ((sgrp = sgr_next())) {
+
+ /*
+ * See if the user was a member of this group
+ */
+ was_member = is_on_list(sgrp->sg_mem, user_name);
+
+ /*
+ * See if the user was an administrator of this group
+ */
+ was_admin = is_on_list(sgrp->sg_adm, user_name);
+
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+ is_member = Gflg && is_on_list(user_groups, sgrp->sg_name);
+
+ if (!was_member && !was_admin && !is_member)
+ continue;
+
+ nsgrp = __sgr_dup(sgrp);
+ if (!nsgrp) {
+ fprintf(stderr,
+ _("%s: out of memory in update_gshadow\n"),
+ Prog);
+ sgr_unlock();
+ return -1;
+ }
+
+ if (was_admin && lflg) {
+ nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
+ nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname);
+ changed = 1;
+ SYSLOG((LOG_INFO,
+ "change admin `%s' to `%s' in shadow group `%s'\n",
+ user_name, user_newname, nsgrp->sg_name));
+ }
+ if (was_member && (!Gflg || is_member)) {
+ if (lflg) {
+ nsgrp->sg_mem = del_list (nsgrp->sg_mem,
+ user_name);
+ nsgrp->sg_mem = add_list (nsgrp->sg_mem,
+ user_newname);
+ changed = 1;
+ SYSLOG((LOG_INFO,
+ "change `%s' to `%s' in shadow group `%s'\n",
+ user_name, user_newname, nsgrp->sg_name));
+ }
+ } else if (was_member && Gflg && !is_member) {
+ nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
+ changed = 1;
+ SYSLOG((LOG_INFO,
+ "delete `%s' from shadow group `%s'\n",
+ user_name, nsgrp->sg_name));
+ } else if (!was_member && Gflg && is_member) {
+ nsgrp->sg_mem = add_list (nsgrp->sg_mem,
+ lflg ? user_newname:user_name);
+ changed = 1;
+ SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n",
+ lflg ? user_newname:user_name,nsgrp->sg_name));
+ }
+ if (!changed)
+ continue;
+
+ changed = 0;
+
+ /*
+ * Update the group entry to reflect the changes.
+ */
+ if (! sgr_update (nsgrp)) {
+ fprintf(stderr,
+ _("%s: error adding new group entry\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error adding shadow group entry\n"));
+ sgr_unlock();
+ return -1;
+ }
+#ifdef NDBM
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
+ if (! sg_dbm_update (nsgrp)) {
+ fprintf(stderr,
+ _("%s: cannot add new dbm group entry\n"),
+ Prog);
+ SYSLOG((LOG_ERR,
+ "error adding dbm shadow group entry\n"));
+ sgr_unlock();
+ return -1;
+ }
+#endif /* NDBM */
+ }
+#ifdef NDBM
+ endsgent ();
+#endif /* NDBM */
+ if (!sgr_close()) {
+ fprintf(stderr, _("%s: cannot rewrite shadow group file\n"),
+ Prog);
+ sgr_unlock();
+ return -1;
+ }
+ sgr_unlock();
+ return 0;
+}
+#endif /* SHADOWGRP */
+
+/*
+ * grp_update - add user to secondary group set
+ *
+ * grp_update() takes the secondary group set given in user_groups
+ * and adds the user to each group given by that set.
+ */
+
+static int
+grp_update(void)
+{
+ int ret;
+
+ ret = update_group();
+#ifdef SHADOWGRP
+ if (!ret && is_shadow_grp)
+ ret = update_gshadow();
+#endif
+ return ret;
+}
+
+#ifdef AUTH_METHODS
+/*
+ * get_password - locate encrypted password in authentication list
+ */
+
+static char *
+get_password(const char *list)
+{
+ char *cp, *end;
+ static char buf[257];
+
+ strcpy (buf, list);
+ for (cp = buf;cp;cp = end) {
+ if ((end = strchr (cp, ';')))
+ *end++ = 0;
+
+ if (cp[0] == '@')
+ continue;
+
+ return cp;
+ }
+ return (char *) 0;
+}
+
+/*
+ * split_auths - break up comma list into (char *) array
+ */
+
+static void
+split_auths(char *list, char **array)
+{
+ char *cp, *end;
+ int i = 0;
+
+ for (cp = list;cp;cp = end) {
+ if ((end = strchr (cp, ';')))
+ *end++ = '\0';
+
+ array[i++] = cp;
+ }
+ array[i] = 0;
+}
+
+/*
+ * update_auths - find list of methods to update
+ */
+
+static void
+update_auths(const char *old, const char *new, char *update)
+{
+ char oldbuf[257], newbuf[257];
+ char *oldv[32], *newv[32], *updatev[32];
+ int i, j, k;
+
+ strcpy (oldbuf, old);
+ split_auths (oldbuf, oldv);
+
+ strcpy (newbuf, new);
+ split_auths (newbuf, newv);
+
+ for (i = j = k = 0;oldv[i];i++) {
+ for (j = 0;newv[j];j++)
+ if (strcmp (oldv[i], newv[j]) != 0)
+ break;
+
+ if (newv[j] != (char *) 0)
+ updatev[k++] = oldv[i];
+ }
+ updatev[k] = 0;
+
+ update[0] = '\0';
+ for (i = 0;updatev[i];i++) {
+ if (i)
+ strcat (update, ";");
+
+ strcat (update, updatev[i]);
+ }
+}
+
+/*
+ * add_auths - find list of methods to add
+ */
+
+static void
+add_auths(const char *old, const char *new, char *add)
+{
+ char oldbuf[257], newbuf[257];
+ char *oldv[32], *newv[32], *addv[32];
+ int i, j, k;
+
+ strcpy (oldbuf, old);
+ split_auths (oldbuf, oldv);
+
+ strcpy (newbuf, new);
+ split_auths (newbuf, newv);
+
+ for (i = j = k = 0;newv[i];i++) {
+ for (j = 0;oldv[j];j++)
+ if (strcmp (oldv[i], newv[j]) == 0)
+ break;
+
+ if (oldv[j] == (char *) 0)
+ addv[k++] = newv[i];
+ }
+ addv[k] = 0;
+
+ add[0] = '\0';
+ for (i = 0;addv[i];i++) {
+ if (i)
+ strcat (add, ";");
+
+ strcat (add, addv[i]);
+ }
+}
+
+/*
+ * delete_auths - find list of methods to delete
+ */
+
+static void
+delete_auths(const char *old, const char *new, char *remove)
+{
+ char oldbuf[257], newbuf[257];
+ char *oldv[32], *newv[32], *removev[32];
+ int i, j, k;
+
+ strcpy (oldbuf, old);
+ split_auths (oldbuf, oldv);
+
+ strcpy (newbuf, new);
+ split_auths (newbuf, newv);
+
+ for (i = j = k = 0;oldv[i];i++) {
+ for (j = 0;newv[j];j++)
+ if (strcmp (oldv[i], newv[j]) == 0)
+ break;
+
+ if (newv[j] == (char *) 0)
+ removev[k++] = oldv[i];
+ }
+ removev[k] = 0;
+
+ remove[0] = '\0';
+ for (i = 0;removev[i];i++) {
+ if (i)
+ strcat (remove, ";");
+
+ strcat (remove, removev[i]);
+ }
+}
+
+/*
+ * convert_auth - convert the argument list to a authentication list
+ */
+
+static void
+convert_auth(char *auths, const char *oldauths, const char *list)
+{
+ char *cp, *end;
+ char *old;
+ char buf[257];
+
+ /*
+ * Copy each method. DEFAULT is replaced by an encrypted string
+ * if one can be found in the current authentication list.
+ */
+
+ strcpy (buf, list);
+ auths[0] = '\0';
+ for (cp = buf;cp;cp = end) {
+ if (auths[0])
+ strcat (auths, ";");
+
+ if ((end = strchr (cp, ',')))
+ *end++ = '\0';
+
+ if (strcmp (cp, "DEFAULT") == 0) {
+ if ((old = get_password (oldauths)))
+ strcat (auths, old);
+ else
+ strcat (auths, "!");
+ } else {
+ strcat (auths, "@");
+ strcat (auths, cp);
+ }
+ }
+}
+
+/*
+ * valid_auth - check authentication list for validity
+ */
+
+static int
+valid_auth(const char *methods)
+{
+ char *cp, *end;
+ char buf[257];
+ int default_cnt = 0;
+
+ /*
+ * Cursory checks, length and illegal characters
+ */
+
+ if ((int) strlen (methods) > 256)
+ return 0;
+
+ if (! VALID (methods))
+ return 0;
+
+ /*
+ * Pick each method apart and check it.
+ */
+
+ strcpy (buf, methods);
+ for (cp = buf;cp;cp = end) {
+ if ((end = strchr (cp, ',')))
+ *end++ = '\0';
+
+ if (strcmp (cp, "DEFAULT") == 0) {
+ if (default_cnt++ > 0)
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
+static long
+get_number(const char *cp)
+{
+ long val;
+ char *ep;
+
+ val = strtol(cp, &ep, 10);
+ if (*cp != '\0' && *ep == '\0') /* valid number */
+ return val;
+
+ fprintf(stderr, _("%s: invalid numeric argument `%s'\n"), Prog, cp);
+ exit(E_BAD_ARG);
+}
+
+/*
+ * process_flags - perform command line argument setting
+ *
+ * process_flags() interprets the command line arguments and sets
+ * the values that the user will be created with accordingly. The
+ * values are checked for sanity.
+ */
+
+static void
+process_flags(int argc, char **argv)
+{
+ const struct group *grp;
+ const struct passwd *pwd;
+#ifdef SHADOWPWD
+ const struct spwd *spwd = NULL;
+#endif
+ int anyflag = 0;
+ int arg;
+
+ if (argc == 1 || argv[argc - 1][0] == '-')
+ usage ();
+
+ if (! (pwd = getpwnam (argv[argc - 1]))) {
+ fprintf(stderr, _("%s: user %s does not exist\n"),
+ Prog, argv[argc - 1]);
+ exit(E_NOTFOUND);
+ }
+ user_name = argv[argc - 1];
+
+#ifdef USE_NIS
+
+ /*
+ * Now make sure it isn't an NIS user.
+ */
+
+ if (__ispwNIS ()) {
+ char *nis_domain;
+ char *nis_master;
+
+ fprintf(stderr, _("%s: user %s is a NIS user\n"),
+ Prog, user_name);
+
+ if (! yp_get_default_domain (&nis_domain) &&
+ ! yp_master (nis_domain, "passwd.byname",
+ &nis_master)) {
+ fprintf(stderr, _("%s: %s is the NIS master\n"),
+ Prog, nis_master);
+ }
+ exit(E_NOTFOUND);
+ }
+#endif
+ user_id = pwd->pw_uid;
+ user_gid = pwd->pw_gid;
+ user_comment = xstrdup(pwd->pw_gecos);
+ user_home = xstrdup(pwd->pw_dir);
+ user_shell = xstrdup(pwd->pw_shell);
+
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && (spwd = getspnam (user_name))) {
+ user_expire = spwd->sp_expire;
+ user_inactive = spwd->sp_inact;
+ }
+#endif
+#ifdef SHADOWPWD
+#define FLAGS "A:u:og:G:d:s:c:mf:e:l:p:LU"
+#else
+#define FLAGS "A:u:og:G:d:s:c:ml:p:LU"
+#endif
+ while ((arg = getopt(argc, argv, FLAGS)) != EOF) {
+#undef FLAGS
+ switch (arg) {
+#ifdef AUTH_METHODS
+ case 'A':
+ if (! valid_auth (optarg)) {
+ fprintf(stderr,
+ _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ auth_arg = optarg;
+ Aflg++;
+ break;
+#endif
+ case 'c':
+ if (! VALID (optarg)) {
+ fprintf(stderr,
+ _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_comment = optarg;
+ cflg++;
+ break;
+ case 'd':
+ if (! VALID (optarg)) {
+ fprintf(stderr,
+ _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ dflg++;
+ user_newhome = optarg;
+ break;
+#ifdef SHADOWPWD
+ case 'e':
+ if (*optarg) {
+ user_expire = strtoday(optarg);
+ if (user_expire == -1) {
+ fprintf(stderr,
+ _("%s: invalid date `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_expire *= DAY/SCALE;
+ } else
+ user_expire = -1;
+ eflg++;
+ break;
+ case 'f':
+ user_inactive = get_number(optarg);
+ fflg++;
+ break;
+#endif
+ case 'g':
+ grp = getgr_nam_gid(optarg);
+ if (!grp) {
+ fprintf(stderr,
+ _("%s: unknown group %s\n"),
+ Prog, optarg);
+ exit(E_NOTFOUND);
+ }
+ user_newgid = grp->gr_gid;
+ gflg++;
+ break;
+ case 'G':
+ if (get_groups(optarg))
+ exit(E_NOTFOUND);
+ Gflg++;
+ break;
+ case 'l':
+ if (!check_user_name(optarg)) {
+ fprintf(stderr,
+ _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+
+ /*
+ * If the name does not really change, we
+ * mustn't set the flag as this will cause
+ * rather serious problems later!
+ */
+
+ if (strcmp (user_name, optarg))
+ lflg++;
+
+ user_newname = optarg;
+ break;
+ case 'L':
+ if (Uflg || pflg)
+ usage ();
+
+ Lflg++;
+ break;
+ case 'm':
+ if (! dflg)
+ usage ();
+
+ mflg++;
+ break;
+ case 'o':
+ if (! uflg)
+ usage ();
+
+ oflg++;
+ break;
+ case 'p':
+ if (Lflg || Uflg)
+ usage ();
+
+ user_pass = optarg;
+ pflg++;
+ break;
+ case 's':
+ if (! VALID (optarg)) {
+ fprintf(stderr,
+ _("%s: invalid field `%s'\n"),
+ Prog, optarg);
+ exit(E_BAD_ARG);
+ }
+ user_shell = optarg;
+ sflg++;
+ break;
+ case 'u':
+ user_newid = get_number(optarg);
+ uflg++;
+ break;
+ case 'U':
+ if (Lflg && pflg)
+ usage ();
+
+ Uflg++;
+ break;
+ default:
+ usage ();
+ }
+ anyflag++;
+ }
+ if (anyflag == 0) {
+ fprintf(stderr, _("%s: no flags given\n"), Prog);
+ exit(E_USAGE);
+ }
+
+#ifdef SHADOWPWD
+ if (!is_shadow_pwd && (eflg || fflg)) {
+ fprintf(stderr,
+ _("%s: shadow passwords required for -e and -f\n"),
+ Prog);
+ exit(E_USAGE);
+ }
+#endif
+
+ if (optind != argc - 1)
+ usage ();
+
+ if (dflg && strcmp (user_home, user_newhome) == 0)
+ dflg = mflg = 0;
+
+ if (uflg && user_id == user_newid)
+ uflg = oflg = 0;
+
+ if (lflg && getpwnam (user_newname)) {
+ fprintf(stderr, _("%s: user %s exists\n"), Prog, user_newname);
+ exit(E_NAME_IN_USE);
+ }
+
+ if (uflg && !oflg && getpwuid(user_newid)) {
+ fprintf(stderr, _("%s: uid %ld is not unique\n"),
+ Prog, (long) user_newid);
+ exit(E_UID_IN_USE);
+ }
+}
+
+/*
+ * close_files - close all of the files that were opened
+ *
+ * close_files() closes all of the files that were opened for this
+ * new user. This causes any modified entries to be written out.
+ */
+
+static void
+close_files(void)
+{
+ if (! pw_close ()) {
+ fprintf(stderr, _("%s: cannot rewrite password file\n"), Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && ! spw_close ()) {
+ fprintf(stderr, _("%s: cannot rewrite shadow password file\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#endif
+#ifdef SHADOWPWD
+ if (is_shadow_pwd)
+ spw_unlock ();
+#endif
+ (void) pw_unlock ();
+
+ /*
+ * Close the DBM and/or flat files
+ */
+
+ endpwent ();
+#ifdef SHADOWPWD
+ endspent ();
+#endif
+ endgrent ();
+#ifdef SHADOWGRP
+ endsgent ();
+#endif
+}
+
+/*
+ * open_files - lock and open the password files
+ *
+ * open_files() opens the two password files.
+ */
+
+static void
+open_files(void)
+{
+ if (!pw_lock()) {
+ fprintf(stderr, _("%s: unable to lock password file\n"), Prog);
+ exit(E_PW_UPDATE);
+ }
+ if (! pw_open (O_RDWR)) {
+ fprintf(stderr, _("%s: unable to open password file\n"), Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#ifdef SHADOWPWD
+ if (is_shadow_pwd && ! spw_lock ()) {
+ fprintf(stderr, _("%s: cannot lock shadow password file\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (is_shadow_pwd && ! spw_open (O_RDWR)) {
+ fprintf(stderr, _("%s: cannot open shadow password file\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#endif
+}
+
+/*
+ * usr_update - create the user entries
+ *
+ * usr_update() creates the password file entries for this user
+ * and will update the group entries if required.
+ */
+
+static void
+usr_update(void)
+{
+ struct passwd pwent;
+ const struct passwd *pwd;
+#ifdef SHADOWPWD
+ struct spwd spent;
+ const struct spwd *spwd = NULL;
+#endif
+#ifdef AUTH_METHODS
+ char old_auth[BUFSIZ];
+ char auth_buf[BUFSIZ];
+#endif
+
+ /*
+ * Locate the entry in /etc/passwd, which MUST exist.
+ */
+
+ pwd = pw_locate(user_name);
+ if (!pwd) {
+ fprintf(stderr, _("%s: %s not found in /etc/passwd\n"),
+ Prog, user_name);
+ fail_exit(E_NOTFOUND);
+ }
+ pwent = *pwd;
+ new_pwent (&pwent);
+
+#ifdef SHADOWPWD
+
+ /*
+ * Locate the entry in /etc/shadow. It doesn't have to
+ * exist, and won't be created if it doesn't.
+ */
+
+ if (is_shadow_pwd && (spwd = spw_locate(user_name))) {
+ spent = *spwd;
+ new_spent (&spent);
+ }
+#endif
+
+#ifdef AUTH_METHODS
+
+#ifdef SHADOWPWD
+ strcpy (old_auth, spwd ? spent.sp_pwdp : pwent.pw_passwd);
+#else
+ strcpy (old_auth, pwent.pw_passwd);
+#endif
+
+ if (Aflg)
+ convert_auth (user_auth, old_auth, auth_arg);
+
+ /*
+ * XXX - this code needs some checking, changing the user name with
+ * "usermod -l new old" clears the password for this user :-(.
+ * For now, just don't define AUTH_METHODS and all will be well.
+ * Most programs don't support "administrator defined authentication
+ * methods" and PAM (when done) will be better anyway :-). --marekm
+ */
+ if (lflg || (Aflg && strcmp (old_auth, user_auth) != 0)) {
+ delete_auths (old_auth, user_auth, auth_buf);
+ if (auth_buf[0] && pw_auth (auth_buf, user_name,
+ PW_DELETE, (char *) 0)) {
+ fprintf(stderr,
+ _("%s: error deleting authentication method\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error deleting auth for `%s'\n",
+ user_name));
+ fail_exit(E_PW_UPDATE);
+ }
+ add_auths (old_auth, user_auth, auth_buf);
+ if (auth_buf[0] == '@' && pw_auth (auth_buf,
+ lflg ? user_newname:user_name, PW_ADD, (char *) 0)) {
+ fprintf(stderr,
+ _("%s: error adding authentication method\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error adding auth for `%s'\n",
+ lflg ? user_newname:user_name));
+ fail_exit(E_PW_UPDATE);
+ }
+ update_auths (old_auth, user_auth, auth_buf);
+ if (lflg && auth_buf[0] == '@' && pw_auth (auth_buf,
+ user_newname, PW_CHANGE, user_name)) {
+ fprintf(stderr,
+ _("%s: error changing authentication method\n"),
+ Prog);
+ SYSLOG((LOG_ERR, "error changing auth for `%s'\n",
+ lflg ? user_newname:user_name));
+ fail_exit(E_PW_UPDATE);
+ }
+#ifdef SHADOWPWD
+ if (spwd)
+ spent.sp_pwdp = user_auth;
+ else
+#endif
+ pwent.pw_passwd = user_auth;
+ }
+#endif /* AUTH_METHODS */
+ if (lflg || uflg || gflg || cflg || dflg || sflg || Aflg || pflg || Lflg || Uflg) {
+ if (! pw_update (&pwent)) {
+ fprintf(stderr,
+ _("%s: error changing password entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (lflg && ! pw_remove (user_name)) {
+ fprintf(stderr,
+ _("%s: error removing password entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+#ifdef NDBM
+ if (pw_dbm_present()) {
+ if (! pw_dbm_update (&pwent)) {
+ fprintf(stderr,
+ _("%s: error adding password dbm entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (lflg && (pwd = getpwnam (user_name)) &&
+ ! pw_dbm_remove (pwd)) {
+ fprintf(stderr,
+ _("%s: error removing passwd dbm entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ }
+#endif
+ }
+#ifdef SHADOWPWD
+ if (spwd && (lflg || eflg || fflg || Aflg || pflg || Lflg || Uflg)) {
+ if (! spw_update (&spent)) {
+ fprintf(stderr,
+ _("%s: error adding new shadow password entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (lflg && ! spw_remove (user_name)) {
+ fprintf(stderr,
+ _("%s: error removing shadow password entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ }
+#ifdef NDBM
+ if (spwd && sp_dbm_present()) {
+ if (! sp_dbm_update (&spent)) {
+ fprintf(stderr,
+ _("%s: error updating shadow passwd dbm entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ if (lflg && ! sp_dbm_remove (user_name)) {
+ fprintf(stderr,
+ _("%s: error removing shadow passwd dbm entry\n"),
+ Prog);
+ fail_exit(E_PW_UPDATE);
+ }
+ }
+#endif /* NDBM */
+#endif /* SHADOWPWD */
+}
+
+/*
+ * move_home - move the user's home directory
+ *
+ * move_home() moves the user's home directory to a new location.
+ * The files will be copied if the directory cannot simply be
+ * renamed.
+ */
+
+static void
+move_home(void)
+{
+ struct stat sb;
+
+ if (mflg && stat (user_home, &sb) == 0) {
+ /*
+ * Don't try to move it if it is not a directory
+ * (but /dev/null for example). --marekm
+ */
+ if (!S_ISDIR(sb.st_mode))
+ return;
+
+ if (access(user_newhome, F_OK) == 0) {
+ fprintf(stderr, _("%s: directory %s exists\n"),
+ Prog, user_newhome);
+ fail_exit(E_HOMEDIR);
+ } else if (rename (user_home, user_newhome)) {
+ if (errno == EXDEV) {
+ if (mkdir (user_newhome, sb.st_mode & 0777)) {
+ fprintf(stderr,
+ _("%s: can't create %s\n"),
+ Prog, user_newhome);
+ }
+ if (chown (user_newhome,
+ sb.st_uid, sb.st_gid)) {
+ fprintf(stderr,
+ _("%s: can't chown %s\n"),
+ Prog, user_newhome);
+ rmdir (user_newhome);
+ fail_exit(E_HOMEDIR);
+ }
+ if (copy_tree (user_home, user_newhome,
+ uflg ? user_newid:-1,
+ gflg ? user_newgid:-1) == 0 &&
+ remove_tree (user_home) == 0 &&
+ rmdir (user_home) == 0)
+ return;
+
+ (void) remove_tree (user_newhome);
+ (void) rmdir (user_newhome);
+ }
+ fprintf(stderr,
+ _("%s: cannot rename directory %s to %s\n"),
+ Prog, user_home, user_newhome);
+ fail_exit(E_HOMEDIR);
+ }
+ }
+ if (uflg || gflg)
+ chown (dflg ? user_newhome:user_home,
+ uflg ? user_newid:user_id,
+ gflg ? user_newgid:user_gid);
+}
+
+/*
+ * update_files - update the lastlog and faillog files
+ */
+
+static void
+update_files(void)
+{
+ struct lastlog ll;
+ struct faillog fl;
+ int fd;
+
+ /*
+ * Relocate the "lastlog" entries for the user. The old entry
+ * is left alone in case the UID was shared. It doesn't hurt
+ * anything to just leave it be.
+ */
+
+ if ((fd = open(LASTLOG_FILE, O_RDWR)) != -1) {
+ lseek(fd, (off_t) user_id * sizeof ll, SEEK_SET);
+ if (read(fd, (char *) &ll, sizeof ll) == sizeof ll) {
+ lseek(fd, (off_t) user_newid * sizeof ll, SEEK_SET);
+ write(fd, (char *) &ll, sizeof ll);
+ }
+ close(fd);
+ }
+
+ /*
+ * Relocate the "faillog" entries in the same manner.
+ */
+
+ if ((fd = open(FAILLOG_FILE, O_RDWR)) != -1) {
+ lseek(fd, (off_t) user_id * sizeof fl, SEEK_SET);
+ if (read(fd, (char *) &fl, sizeof fl) == sizeof fl) {
+ lseek(fd, (off_t) user_newid * sizeof fl, SEEK_SET);
+ write(fd, (char *) &fl, sizeof fl);
+ }
+ close(fd);
+ }
+}
+
+#ifndef NO_MOVE_MAILBOX
+/*
+ * This is the new and improved code to carefully chown/rename the user's
+ * mailbox. Maybe I am too paranoid but the mail spool dir sometimes
+ * happens to be mode 1777 (this makes mail user agents work without
+ * being setgid mail, but is NOT recommended; they all should be fixed
+ * to use movemail). --marekm
+ */
+static void
+move_mailbox(void)
+{
+ const char *maildir;
+ char mailfile[1024], newmailfile[1024];
+ int fd;
+ struct stat st;
+
+ maildir = getdef_str("MAIL_DIR");
+#ifdef MAIL_SPOOL_DIR
+ if (!maildir && !getdef_str("MAIL_FILE"))
+ maildir = MAIL_SPOOL_DIR;
+#endif
+ if (!maildir)
+ return;
+
+ /*
+ * O_NONBLOCK is to make sure open won't hang on mandatory locks.
+ * We do fstat/fchown to make sure there are no races (someone
+ * replacing /var/spool/mail/luser with a hard link to /etc/passwd
+ * between stat and chown). --marekm
+ */
+
+ snprintf(mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
+ fd = open(mailfile, O_RDONLY | O_NONBLOCK, 0);
+ if (fd < 0) {
+ /* no need for warnings if the mailbox doesn't exist */
+ if (errno != ENOENT)
+ perror(mailfile);
+ return;
+ }
+ if (fstat(fd, &st) < 0) {
+ perror("fstat");
+ close(fd);
+ return;
+ }
+ if (st.st_uid != user_id) {
+ /* better leave it alone */
+ fprintf(stderr, _("%s: warning: %s not owned by %s\n"),
+ Prog, mailfile, user_name);
+ close(fd);
+ return;
+ }
+ if (uflg && fchown(fd, user_newid, (gid_t) -1) < 0)
+ perror(_("failed to change mailbox owner"));
+
+ close(fd);
+
+ if (lflg) {
+ snprintf(newmailfile, sizeof newmailfile, "%s/%s", maildir, user_newname);
+ if (link(mailfile, newmailfile) || unlink(mailfile))
+ perror(_("failed to rename mailbox"));
+ }
+}
+#endif
+
+/*
+ * main - usermod command
+ */
+
+int
+main(int argc, char **argv)
+{
+ int grp_err = 0;
+
+ /*
+ * Get my name so that I can use it to report errors.
+ */
+ Prog = Basename(argv[0]);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ OPENLOG(Prog);
+
+#ifdef SHADOWPWD
+ is_shadow_pwd = spw_file_present();
+#endif
+#ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present();
+#endif
+
+ /*
+ * The open routines for the NDBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
+
+#ifdef NDBM
+ pw_dbm_mode = O_RDWR;
+#ifdef SHADOWPWD
+ sp_dbm_mode = O_RDWR;
+#endif
+ gr_dbm_mode = O_RDWR;
+#ifdef SHADOWGRP
+ sg_dbm_mode = O_RDWR;
+#endif
+#endif /* NDBM */
+ process_flags (argc, argv);
+
+ /*
+ * Do the hard stuff - open the files, change the user entries,
+ * change the home directory, then close and update the files.
+ */
+
+ open_files();
+
+ usr_update();
+
+ close_files();
+
+ if (Gflg || lflg)
+ grp_err = grp_update();
+
+ if (mflg)
+ move_home();
+
+#ifndef NO_MOVE_MAILBOX
+ if (lflg || uflg)
+ move_mailbox();
+#endif
+
+ if (uflg) {
+ update_files();
+
+ /*
+ * Change the UID on all of the files owned by `user_id'
+ * to `user_newid' in the user's home directory.
+ */
+
+ chown_tree(dflg ? user_newhome:user_home,
+ user_id, user_newid,
+ user_gid, gflg ? user_newgid:user_gid);
+ }
+
+ if (grp_err)
+ exit(E_GRP_UPDATE);
+
+ exit(E_SUCCESS);
+ /*NOTREACHED*/
+}
diff --git a/current/src/vipw.c b/current/src/vipw.c
new file mode 100644
index 00000000..ed450d47
--- /dev/null
+++ b/current/src/vipw.c
@@ -0,0 +1,252 @@
+/*
+ vipw, vigr edit the password or group file
+ with -s will edit shadow or gshadow file
+
+ Copyright (C) 1997 Guy Maor <maor@ece.utexas.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <config.h>
+
+#include "rcsid.h"
+RCSID(PKG_VER "$Id: vipw.c,v 1.2 2000/08/26 18:27:19 marekm Exp $")
+
+#include "defines.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <utime.h>
+#include "prototypes.h"
+#include "pwio.h"
+#include "shadowio.h"
+#include "groupio.h"
+#include "sgroupio.h"
+
+
+static const char *progname, *filename, *fileeditname;
+static int filelocked = 0, createedit = 0;
+static int (*unlock)(void);
+
+/* local function prototypes */
+static int create_backup_file(FILE *, const char *, struct stat *);
+static void vipwexit(const char *, int, int);
+static void vipwedit(const char *, int (*)(void), int (*)(void));
+
+static int
+create_backup_file(FILE *fp, const char *backup, struct stat *sb)
+{
+ struct utimbuf ub;
+ FILE *bkfp;
+ int c;
+ mode_t mask;
+
+ mask = umask(077);
+ bkfp = fopen(backup, "w");
+ umask(mask);
+ if (!bkfp) return -1;
+
+ rewind(fp);
+ while ((c = getc(fp)) != EOF) {
+ if (putc(c, bkfp) == EOF) break;
+ }
+
+ if (c != EOF || fflush(bkfp)) {
+ fclose(bkfp);
+ unlink(backup);
+ return -1;
+ }
+ if (fclose(bkfp)) {
+ unlink(backup);
+ return -1;
+ }
+
+ ub.actime = sb->st_atime;
+ ub.modtime = sb->st_mtime;
+ if (utime(backup, &ub) ||
+ chmod(backup, sb->st_mode) ||
+ chown(backup, sb->st_uid, sb->st_gid)) {
+ unlink(backup);
+ return -1;
+ }
+ return 0;
+}
+
+
+static void
+vipwexit(const char *msg, int syserr, int ret)
+{
+ int err = errno;
+ if (filelocked) (*unlock)();
+ if (createedit) unlink(fileeditname);
+ if (msg) fprintf(stderr, "%s: %s", progname, msg);
+ if (syserr) fprintf(stderr, ": %s", strerror(err));
+ fprintf(stderr, _("\n%s: %s is unchanged\n"), progname, filename);
+ exit(ret);
+}
+
+#ifndef DEFAULT_EDITOR
+#define DEFAULT_EDITOR "vi"
+#endif
+
+static void
+vipwedit(const char *file, int (*file_lock)(void), int (*file_unlock)(void))
+{
+ const char *editor;
+ pid_t pid;
+ struct stat st1, st2;
+ int status;
+ FILE *f;
+ char filebackup[1024], fileedit[1024];
+
+ snprintf(filebackup, sizeof filebackup, "%s-", file);
+ snprintf(fileedit, sizeof fileedit, "%s.edit", file);
+ unlock = file_unlock;
+ filename = file;
+ fileeditname = fileedit;
+
+ if (access(file, F_OK)) vipwexit(file, 1, 1);
+ if (!file_lock()) vipwexit(_("Couldn't lock file"), errno, 5);
+ filelocked = 1;
+
+ /* edited copy has same owners, perm */
+ if (stat(file, &st1)) vipwexit(file, 1, 1);
+ if (!(f = fopen(file, "r"))) vipwexit(file, 1, 1);
+ if (create_backup_file(f, fileedit, &st1))
+ vipwexit(_("Couldn't make backup"), errno, 1);
+ createedit = 1;
+
+ editor = getenv("VISUAL");
+ if (!editor)
+ editor = getenv("EDITOR");
+ if (!editor)
+ editor = DEFAULT_EDITOR;
+
+ if ((pid = fork()) == -1) vipwexit("fork", 1, 1);
+ else if (!pid) {
+#if 0
+ execlp(editor, editor, fileedit, (char *) 0);
+ fprintf(stderr, "%s: %s: %s\n", progname, editor, strerror(errno));
+ exit(1);
+#else
+ /* use the system() call to invoke the editor so that it accepts
+ command line args in the EDITOR and VISUAL environment vars */
+ char *buf;
+ buf = (char *) malloc (strlen(editor) + strlen(fileedit) + 2);
+ snprintf(buf, strlen(editor) + strlen(fileedit) + 2, "%s %s",
+ editor, fileedit);
+ if (system(buf) != 0) {
+ fprintf(stderr, "%s: %s: %s\n", progname, editor, strerror(errno));
+ exit(1);
+ } else
+ exit(0);
+#endif
+ }
+
+ for (;;) {
+ pid = waitpid(pid, &status, WUNTRACED);
+ if (WIFSTOPPED(status)) {
+ kill(getpid(), SIGSTOP);
+ kill(getpid(), SIGCONT);
+ }
+ else break;
+ }
+
+ if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status))
+ vipwexit(editor, 1, 1);
+
+ if (stat(fileedit, &st2)) vipwexit(fileedit, 1, 1);
+ if (st1.st_mtime == st2.st_mtime) vipwexit(0, 0, 0);
+
+ /* XXX - here we should check fileedit for errors; if there are any,
+ ask the user what to do (edit again, save changes anyway, or quit
+ without saving). Use pwck or grpck to do the check. --marekm */
+
+ createedit = 0;
+ unlink(filebackup);
+ link(file, filebackup);
+ if (rename(fileedit, file) == -1) {
+ fprintf(stderr, _("%s: can't restore %s: %s (your changes are in %s)\n"),
+ progname, file, strerror(errno), fileedit);
+ vipwexit(0,0,1);
+ }
+
+ (*file_unlock)();
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int flag;
+ int editshadow = 0;
+ char *c;
+ int e = 1;
+ int do_vipw;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ progname = ((c = strrchr(*argv, '/')) ? c+1 : *argv);
+ do_vipw = (strcmp(progname, "vigr") != 0);
+
+ while ((flag = getopt(argc, argv, "ghps")) != EOF) {
+ switch (flag) {
+ case 'p':
+ do_vipw = 1;
+ break;
+ case 'g':
+ do_vipw = 0;
+ break;
+ case 's':
+ editshadow = 1;
+ break;
+ case 'h':
+ e = 0;
+ default:
+ printf(_("Usage:\n\
+`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n\
+`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n\
+"));
+ exit(e);
+ }
+ }
+
+ if (do_vipw) {
+#ifdef SHADOWPWD
+ if (editshadow)
+ vipwedit(SHADOW_FILE, spw_lock, spw_unlock);
+ else
+#endif
+ vipwedit(PASSWD_FILE, pw_lock, pw_unlock);
+ }
+ else {
+#ifdef SHADOWGRP
+ if (editshadow)
+ vipwedit(SGROUP_FILE, sgr_lock, sgr_unlock);
+ else
+#endif
+ vipwedit(GROUP_FILE, gr_lock, gr_unlock);
+ }
+
+ return 0;
+}
diff --git a/current/stamp-h.in b/current/stamp-h.in
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/current/stamp-h.in
@@ -0,0 +1 @@
+timestamp