aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/Makefile2
-rw-r--r--lib/libc/compat-43/Makefile.inc5
-rw-r--r--lib/libc/compat-43/setrgid.c (renamed from lib/libc/gen/setrgid.c)15
-rw-r--r--lib/libc/compat-43/setruid.c (renamed from lib/libc/gen/setruid.c)15
-rw-r--r--lib/libc/db/hash/hash.c2
-rw-r--r--lib/libc/db/recno/rec_open.c2
-rw-r--r--lib/libc/gen/Makefile.inc13
-rw-r--r--lib/libc/gen/ctype_.c8
-rw-r--r--lib/libc/gen/getcap.32
-rw-r--r--lib/libc/gen/getcap.c29
-rw-r--r--lib/libc/gen/getfsent.32
-rw-r--r--lib/libc/gen/getmntinfo.32
-rw-r--r--lib/libc/gen/getpwent.314
-rw-r--r--lib/libc/gen/getpwent.c93
-rw-r--r--lib/libc/gen/semconfig.c2
-rw-r--r--lib/libc/gen/setmode.c11
-rw-r--r--lib/libc/i386/DEFS.h2
-rw-r--r--lib/libc/i386/string/bcmp.S11
-rw-r--r--lib/libc/i386/string/memcmp.S15
-rw-r--r--lib/libc/i386/string/memmove.S17
-rw-r--r--lib/libc/i386/string/memset.S16
-rw-r--r--lib/libc/i386/string/strcmp.S4
-rw-r--r--lib/libc/i386/string/strncmp.S69
-rw-r--r--lib/libc/locale/Makefile.inc18
-rw-r--r--lib/libc/locale/ansi.c148
-rw-r--r--lib/libc/locale/euc.4231
-rw-r--r--lib/libc/locale/euc.c220
-rw-r--r--lib/libc/locale/frune.c103
-rw-r--r--lib/libc/locale/isctype.c (renamed from lib/libc/gen/isctype.c)86
-rw-r--r--lib/libc/locale/mbrune.3157
-rw-r--r--lib/libc/locale/mbrune.c112
-rw-r--r--lib/libc/locale/multibyte.3241
-rw-r--r--lib/libc/locale/none.c (renamed from lib/libc/stdlib/multibyte.c)102
-rw-r--r--lib/libc/locale/rune.3269
-rw-r--r--lib/libc/locale/rune.c334
-rw-r--r--lib/libc/locale/setlocale.3321
-rw-r--r--lib/libc/locale/setlocale.c198
-rw-r--r--lib/libc/locale/table.c160
-rw-r--r--lib/libc/locale/utf2.487
-rw-r--r--lib/libc/locale/utf2.c148
-rw-r--r--lib/libc/net/gethostnamadr.c1
-rw-r--r--lib/libc/net/ns_addr.c4
-rw-r--r--lib/libc/net/rcmd.c30
-rw-r--r--lib/libc/stdio/Makefile.inc7
-rw-r--r--lib/libc/stdio/fclose.c2
-rw-r--r--lib/libc/stdio/fgetline.c1
-rw-r--r--lib/libc/stdio/fgetln.3 (renamed from lib/libc/stdio/fgetline.3)52
-rw-r--r--lib/libc/stdio/fgetln.c162
-rw-r--r--lib/libc/stdio/fseek.c2
-rw-r--r--lib/libc/stdio/gets.c13
-rw-r--r--lib/libc/stdio/local.h2
-rw-r--r--lib/libc/stdio/printf.32
-rw-r--r--lib/libc/stdlib/Makefile.inc2
-rw-r--r--lib/libc/stdlib/rand.c2
-rw-r--r--lib/libc/string/index.32
-rw-r--r--lib/libc/string/strftime.c1
-rw-r--r--lib/libc/sys/Makefile.inc9
-rw-r--r--lib/libc/sys/execve.22
-rw-r--r--lib/libc/sys/setregid.22
-rw-r--r--lib/libc/sys/setreuid.22
-rw-r--r--lib/libc/sys/setuid.2 (renamed from lib/libc/gen/setuid.3)64
-rw-r--r--lib/libc/sys/sigsuspend.24
62 files changed, 3381 insertions, 273 deletions
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index 319a528c5a54..fe11e19456a1 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -15,7 +15,9 @@ INSTALL_PIC_ARCHIVE=
.include "${.CURDIR}/gen/Makefile.inc"
.include "${.CURDIR}/locale/Makefile.inc"
.include "${.CURDIR}/net/Makefile.inc"
+.if defined(GCC1_IN_LIBC)
.include "${.CURDIR}/quad/Makefile.inc"
+.endif
.include "${.CURDIR}/stdio/Makefile.inc"
.include "${.CURDIR}/stdlib/Makefile.inc"
.include "${.CURDIR}/string/Makefile.inc"
diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc
index 63c330fcd813..bcb3d1efe3cb 100644
--- a/lib/libc/compat-43/Makefile.inc
+++ b/lib/libc/compat-43/Makefile.inc
@@ -1,9 +1,10 @@
-# @(#)Makefile.inc 5.3 (Berkeley) 2/20/91
+# From: @(#)Makefile.inc 5.3 (Berkeley) 2/20/91
+# $Id: Makefile.inc,v 1.5 1994/04/04 19:33:56 wollman Exp $
# compat-43 sources
.PATH: ${.CURDIR}/${MACHINE}/compat-43 ${.CURDIR}/compat-43
-SRCS+= creat.c getwd.c killpg.c setpgrp.c sigcompat.c
+SRCS+= creat.c getwd.c killpg.c setpgrp.c sigcompat.c setruid.c setrgid.c
MAN2+= compat-43/creat.2 compat-43/killpg.2 compat-43/sigblock.2 \
compat-43/sigpause.2 compat-43/sigsetmask.2 compat-43/sigvec.2
diff --git a/lib/libc/gen/setrgid.c b/lib/libc/compat-43/setrgid.c
index 43492306191e..50484554ac8b 100644
--- a/lib/libc/gen/setrgid.c
+++ b/lib/libc/compat-43/setrgid.c
@@ -32,10 +32,16 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)setrgid.c 5.5 (Berkeley) 2/23/91";
+static char sccsid[] = "From: @(#)setrgid.c 5.5 (Berkeley) 2/23/91";
+static const char rcsid[] =
+ "$Id: setrgid.c,v 1.5 1994/04/23 23:52:45 wollman Exp $";
#endif /* LIBC_SCCS and not lint */
#include <unistd.h>
+#include <string.h>
+
+#define MESSAGE ": warning: this program uses setrgid(), which doesn't do anything\r\n(but used to)\r\n"
+
int
#ifdef __STDC__
@@ -45,6 +51,11 @@ setrgid(rgid)
int rgid;
#endif
{
-
+ extern char *__progname;
+ write(2, __progname, strlen(__progname));
+ write(2, MESSAGE, sizeof(MESSAGE) - 1);
return (setregid(rgid, -1));
}
+
+asm(".stabs \"warning: setrgid function referenced\", 30, 0,0,0");
+asm(".stabs \"_setrgid\", 1, 0, 0, 0");
diff --git a/lib/libc/gen/setruid.c b/lib/libc/compat-43/setruid.c
index 1c224a33095d..72171a57b30d 100644
--- a/lib/libc/gen/setruid.c
+++ b/lib/libc/compat-43/setruid.c
@@ -32,10 +32,15 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)setruid.c 5.5 (Berkeley) 2/23/91";
+static char sccsid[] = "From: @(#)setruid.c 5.5 (Berkeley) 2/23/91";
+static const char rcsid[] =
+ "$Id: setruid.c,v 1.4 1994/04/23 20:39:02 wollman Exp $";
#endif /* LIBC_SCCS and not lint */
#include <unistd.h>
+#include <string.h>
+
+#define MESSAGE ": warning: this program uses setruid, which doesn't do anything\r\n(but used to)\r\n"
int
#ifdef __STDC__
@@ -45,6 +50,12 @@ setruid(ruid)
int ruid;
#endif
{
-
+ extern char *__progname;
+ write(2, __progname, strlen(__progname));
+ write(2, MESSAGE, sizeof(MESSAGE) - 1);
return (setreuid(ruid, -1));
}
+
+asm(".stabs \"warning: setruid function referenced\", 30, 0, 0, 0");
+asm(".stabs \"_setruid\", 1, 0, 0, 0");
+
diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
index e9b25831d20e..c6a52d738973 100644
--- a/lib/libc/db/hash/hash.c
+++ b/lib/libc/db/hash/hash.c
@@ -433,6 +433,8 @@ hdestroy(hashp)
if (hashp->fp != -1)
(void)close(hashp->fp);
+ free(hashp);
+
if (save_errno) {
errno = save_errno;
return (ERROR);
diff --git a/lib/libc/db/recno/rec_open.c b/lib/libc/db/recno/rec_open.c
index f05a44bb0026..514e9811f91a 100644
--- a/lib/libc/db/recno/rec_open.c
+++ b/lib/libc/db/recno/rec_open.c
@@ -160,7 +160,7 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
else {
t->bt_msize = sb.st_size;
if ((t->bt_smap = mmap(NULL, t->bt_msize,
- PROT_READ, MAP_PRIVATE, rfd,
+ PROT_READ, MAP_FILE|MAP_PRIVATE, rfd,
(off_t)0)) == (caddr_t)-1)
goto slow;
t->bt_cmap = t->bt_smap;
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 0f0a66405d13..3b54c31a5d12 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -8,10 +8,10 @@ SRCS+= alarm.c assert.c clock.c crypt.c ctermid.c ctime.c ctype_.c \
fnmatch.c frexp.c fstab.c fts.c getcap.c getcwd.c getgrent.c \
getlogin.c getmntinfo.c getpass.c getpwent.c getsubopt.c getttyent.c \
getusershell.c glob.c infinity.c initgroups.c insque.c isatty.c \
- isctype.c isinf.c mktemp.c msgctl.c msgget.c msgsnd.c msgrcv.c \
+ isinf.c mktemp.c msgctl.c msgget.c msgsnd.c msgrcv.c \
nice.c nlist.c pause.c popen.c psignal.c raise.c scandir.c \
semconfig.c semctl.c semget.c semop.c \
- setjmperr.c setmode.c setrgid.c setruid.c \
+ setjmperr.c setmode.c \
shmat.c shmctl.c shmdt.c shmget.c \
siginterrupt.c siglist.c signal.c sigsetops.c sleep.c syslog.c \
termios.c time.c times.c timezone.c ttyname.c ttyslot.c \
@@ -27,7 +27,9 @@ SRCS+= adddf3.s addsf3.s ashlsi3.s ashrsi3.s cmpdf2.s cmpsf2.s divdf3.s \
umodsi3.s umulsi3.s
.elif (${MACHINE} == "i386")
SRCS+= _setjmp.S alloca.S fabs.S ldexp.c modf.S setjmp.S sigsetjmp.S
+.if defined (GCC1_IN_LIBC)
SRCS+= divsi3.S fixdfsi.S fixunsdfsi.S udivsi3.S
+.endif
.elif (${MACHINE} == "tahoe")
CFLAGS+=-I/sys
SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s
@@ -36,6 +38,9 @@ SRCS+= udiv.s urem.s
SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s
SRCS+= udiv.s urem.s
.endif
+.if defined (PW_COMPACT)
+CFLAGS+=-DPW_COMPACT
+.endif
MAN3+= gen/alarm.3 gen/clock.3 gen/crypt.3 gen/ctermid.3 gen/ctime.3 \
gen/ctype.3 gen/directory.3 gen/err.3 gen/exec.3 gen/fnmatch.3 \
@@ -47,7 +52,7 @@ MAN3+= gen/alarm.3 gen/clock.3 gen/crypt.3 gen/ctermid.3 gen/ctime.3 \
gen/islower.3 gen/isprint.3 gen/ispunct.3 gen/isspace.3 \
gen/isupper.3 gen/isxdigit.3 gen/ldexp.3 gen/modf.3 gen/nice.3 \
gen/nlist.3 gen/pause.3 gen/popen.3 gen/psignal.3 gen/raise.3 \
- gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \
+ gen/scandir.3 gen/setjmp.3 gen/setmode.3 \
gen/siginterrupt.3 gen/signal.3 gen/sigsetops.3 gen/sleep.3 \
gen/syslog.3 gen/tcgetpgrp.3 gen/tcsendbreak.3 gen/tcsetattr.3 \
gen/tcsetpgrp.3 gen/time.3 gen/times.3 gen/timezone.3 gen/tolower.3 \
@@ -86,8 +91,6 @@ MLINKS+=scandir.3 alphasort.3
MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
setjmp.3 sigsetjmp.3 setjmp.3 siglongjmp.3 setjmp.3 longjmperror.3
MLINKS+=setmode.3 getmode.3
-MLINKS+=setuid.3 setegid.3 setuid.3 seteuid.3 setuid.3 setgid.3 \
- setuid.3 setrgid.3 setuid.3 setruid.3
MLINKS+=sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \
sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \
sigsetops.3 sigismember.3
diff --git a/lib/libc/gen/ctype_.c b/lib/libc/gen/ctype_.c
index d361c1617cea..0f06fe2b8123 100644
--- a/lib/libc/gen/ctype_.c
+++ b/lib/libc/gen/ctype_.c
@@ -5,7 +5,7 @@
* or UNIX System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
- * $Id: ctype_.c,v 1.1.1.1.2.1 1994/05/04 07:39:42 rgrimes Exp $
+ * $Id: ctype_.c,v 1.3 1994/05/04 08:17:14 rgrimes Exp $
*/
/*
* Copyright (c) 1989 The Regents of the University of California.
@@ -41,10 +41,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ctype_.c 5.6 (Berkeley) 6/1/90";
+static char sccsid[] = "From: @(#)ctype_.c 5.6 (Berkeley) 6/1/90";
+static const char rcsid[] =
+ "$Id: ctype_.c,v 1.3 1994/05/04 08:17:14 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
-#include <ctype.h>
+#include <octype.h>
char _ctype_[1 + 256] = {
0,
diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3
index d18b3797bc7e..a2cf2665d0d4 100644
--- a/lib/libc/gen/getcap.3
+++ b/lib/libc/gen/getcap.3
@@ -33,7 +33,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)getcap.3 5.4 (Berkeley) 8/11/92
-.\" $Id: getcap.3,v 1.1.2.1 1994/05/01 16:05:00 jkh Exp $
+.\" $Id: getcap.3,v 1.2 1994/04/17 09:16:14 alm Exp $
.\"
.Dd "August 11, 1992"
.Dt GETCAP 3
diff --git a/lib/libc/gen/getcap.c b/lib/libc/gen/getcap.c
index 7f70789450fd..647a5bff41a7 100644
--- a/lib/libc/gen/getcap.c
+++ b/lib/libc/gen/getcap.c
@@ -35,7 +35,8 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getcap.c 5.15 (Berkeley) 3/19/93";
+/*static char *sccsid = "from: @(#)getcap.c 5.15 (Berkeley) 3/19/93";*/
+static char *rcsid = "$Id: getcap.c,v 1.2 1994/04/17 09:16:16 alm Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -194,8 +195,8 @@ getent(cap, len, db_array, fd, name, depth, nfield)
DB *capdbp;
DBT key, data;
register char *r_end, *rp, **db_p;
- int myfd, eof, foundit, retval;
- char *record;
+ int myfd, eof, foundit, retval, clen;
+ char *record, *cbuf;
int tc_not_resolved;
char pbuf[_POSIX_PATH_MAX];
@@ -250,11 +251,21 @@ getent(cap, len, db_array, fd, name, depth, nfield)
!= NULL) {
free(record);
retval = cdbget(capdbp, &record, name);
- if (capdbp->close(capdbp) < 0)
+ if (retval < 0) {
+ /* no record available */
+ (void)capdbp->close(capdbp);
+ return (retval);
+ }
+ /* save the data; close frees it */
+ clen = strlen(record);
+ cbuf = malloc(clen + 1);
+ memcpy(cbuf, record, clen + 1);
+ if (capdbp->close(capdbp) < 0) {
+ free(cbuf);
return (-2);
- *len = strlen(record);
- *cap = malloc(*len + 1);
- memmove(*cap, record, *len + 1);
+ }
+ *len = clen;
+ *cap = cbuf;
return (retval);
} else {
fd = open(*db_p, O_RDONLY, 0);
@@ -657,7 +668,7 @@ cgetnext(bp, db_array)
gottoprec = 1;
line = toprec;
} else {
- line = fgetline(pfp, &len);
+ line = fgetln(pfp, &len);
if (line == NULL && pfp) {
(void)fclose(pfp);
if (ferror(pfp)) {
@@ -716,7 +727,7 @@ cgetnext(bp, db_array)
*np = '\0';
break;
} else { /* name field extends beyond the line */
- line = fgetline(pfp, &len);
+ line = fgetln(pfp, &len);
if (line == NULL && pfp) {
(void)fclose(pfp);
if (ferror(pfp)) {
diff --git a/lib/libc/gen/getfsent.3 b/lib/libc/gen/getfsent.3
index 16847ed0b5f7..e29ed40724df 100644
--- a/lib/libc/gen/getfsent.3
+++ b/lib/libc/gen/getfsent.3
@@ -43,7 +43,7 @@
.Nd get file system descriptor file entry
.Sh SYNOPSIS
.Fd #include <fstab.h>
-.Ft fstab *
+.Ft struct fstab *
.Fn getfsent void
.Ft struct fstab *
.Fn getfsspec "const char *spec"
diff --git a/lib/libc/gen/getmntinfo.3 b/lib/libc/gen/getmntinfo.3
index 6119c6a4b2b7..689a28e3ddbf 100644
--- a/lib/libc/gen/getmntinfo.3
+++ b/lib/libc/gen/getmntinfo.3
@@ -41,7 +41,7 @@
.Fd #include <sys/types.h>
.Fd #include <sys/mount.h>
.Ft int
-.Fn getmntinfo "int mntbufp" "int flags"
+.Fn getmntinfo "int *mntbufp" "int flags"
.Sh DESCRIPTION
The
.Fn getmntinfo
diff --git a/lib/libc/gen/getpwent.3 b/lib/libc/gen/getpwent.3
index 6d0b9194bb0b..7963afab91e6 100644
--- a/lib/libc/gen/getpwent.3
+++ b/lib/libc/gen/getpwent.3
@@ -200,6 +200,20 @@ and
.Fn setpwent
are fairly useless in a networked environment and should be
avoided, if possible.
+.Pp
+Standard database make routines are slow especially for big passwd
+files. Moreover, *pwd.db bases are too big and waste root space.
+You can have much faster routines with small *pwd.db,
+but loose binary compatibility
+with previous versions and with other BSD-like systems.
+If you want to setup much faster routines, define
+.B PW_COMPACT
+envirnoment variable (f.e. 'setenv PW_COMPACT' in csh) and use
+.I bootstrappwd
+target into /usr/src/Makefile.
+If you will want to return this changes back, use the same target
+without defining
+.BR PW_COMPACT .
.Sh COMPATIBILITY
The historic function
.Xr setpwfile 3 ,
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
index 93a09ee52ff6..96ae370c761c 100644
--- a/lib/libc/gen/getpwent.c
+++ b/lib/libc/gen/getpwent.c
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)getpwent.c 5.21 (Berkeley) 3/14/91";*/
-static char *rcsid = "$Id: getpwent.c,v 1.4 1994/01/11 19:00:58 nate Exp $";
+static char *rcsid = "$Id: getpwent.c,v 1.9 1994/05/05 18:16:44 ache Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -54,8 +54,14 @@ static char *rcsid = "$Id: getpwent.c,v 1.4 1994/01/11 19:00:58 nate Exp $";
#include <rpcsvc/ypclnt.h>
#endif
+/* #define PW_COMPACT */
+/* Compact pwd.db/spwd.db structure by Alex G. Bulushev, bag@demos.su */
+
static struct passwd _pw_passwd; /* password structure */
static DB *_pw_db; /* password database */
+#ifdef PW_COMPACT
+static DB *_spw_db; /* shadow password database */
+#endif
static int _pw_keynum; /* key counter */
static int _pw_stayopen; /* keep fd's open */
static int __hashpw(), __initdb();
@@ -260,6 +266,12 @@ getpwnam(name)
if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
return &_pw_passwd;
}
@@ -268,6 +280,12 @@ getpwnam(name)
if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
return (struct passwd *)NULL;
}
@@ -283,6 +301,12 @@ getpwnam(name)
if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
return(rval ? &_pw_passwd : (struct passwd *)NULL);
}
@@ -355,6 +379,12 @@ getpwuid(uid)
if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
return &_pw_passwd;
}
@@ -363,6 +393,12 @@ getpwuid(uid)
if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
return (struct passwd *)NULL;
}
@@ -378,6 +414,12 @@ getpwuid(uid)
if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
return(rval ? &_pw_passwd : (struct passwd *)NULL);
}
@@ -410,6 +452,12 @@ endpwent()
if (_pw_db) {
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
+#ifdef PW_COMPACT
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#endif
}
#ifdef YP
__ypmode = 0;
@@ -425,12 +473,30 @@ __initdb()
static int warned;
char *p;
+#ifdef PW_COMPACT
+ if (!geteuid()) {
+ _spw_db = dbopen(_PATH_SMP_DB, O_RDONLY, 0, DB_HASH, NULL);
+ if (!_spw_db && !warned)
+ syslog(LOG_ERR, "%s: %m", _PATH_SMP_DB);
+ }
+ _pw_db = dbopen(_PATH_MP_DB, O_RDONLY, 0, DB_HASH, NULL);
+ if (_pw_db)
+ return(1);
+ if (!warned)
+ syslog(LOG_ERR, "%s: %m", _PATH_MP_DB);
+ if (_spw_db) {
+ (void)(_spw_db->close)(_spw_db);
+ _spw_db = (DB *)NULL;
+ }
+#else
p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
_pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL);
if (_pw_db)
return(1);
if (!warned)
syslog(LOG_ERR, "%s: %m", p);
+#endif
+ warned = 1;
return(0);
}
@@ -442,9 +508,26 @@ __hashpw(key)
static u_int max;
static char *line;
DBT data;
+#ifdef PW_COMPACT
+ DBT _key, *__key;
+ char bf[sizeof(_pw_keynum) + 1];
+#endif
if ((_pw_db->get)(_pw_db, key, &data, 0))
return(0);
+#ifdef PW_COMPACT
+ __key = key;
+ if (((char *)(*__key).data)[0] != _PW_KEYBYNUM) {
+ if (data.size != sizeof(_pw_keynum)) return(0);
+ bf[0] = _PW_KEYBYNUM;
+ bcopy(data.data, bf + 1, sizeof(_pw_keynum));
+ _key.data = (u_char *)bf;
+ _key.size = sizeof(_pw_keynum) + 1;
+ __key = (DBT *)&_key;
+ if ((_pw_db->get)(_pw_db, __key, &data, 0))
+ return(0);
+ }
+#endif
p = (char *)data.data;
if (data.size > max && !(line = realloc(line, max += 1024)))
return(0);
@@ -452,7 +535,9 @@ __hashpw(key)
t = line;
#define EXPAND(e) e = t; while (*t++ = *p++);
EXPAND(_pw_passwd.pw_name);
+#ifndef PW_COMPACT
EXPAND(_pw_passwd.pw_passwd);
+#endif
bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
p += sizeof(int);
bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
@@ -465,5 +550,11 @@ __hashpw(key)
EXPAND(_pw_passwd.pw_shell);
bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
p += sizeof(time_t);
+#ifdef PW_COMPACT
+ if (_spw_db && !(_spw_db->get)(_spw_db, __key, &data, 0))
+ p = (char *)data.data;
+ else p = "*";
+ EXPAND(_pw_passwd.pw_passwd);
+#endif
return(1);
}
diff --git a/lib/libc/gen/semconfig.c b/lib/libc/gen/semconfig.c
index 66fbb2d93398..cf5399b6dde4 100644
--- a/lib/libc/gen/semconfig.c
+++ b/lib/libc/gen/semconfig.c
@@ -5,7 +5,7 @@
#if __STDC__
int semconfig(int cmd, int p1, int p2, int p3)
#else
-int semctl(cmd, p1, p2, p3)
+int semconfig(cmd, p1, p2, p3)
int cmd, p1, p2, p3;
#endif
{
diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c
index 12f7c1ab1ca7..9858beaa4a06 100644
--- a/lib/libc/gen/setmode.c
+++ b/lib/libc/gen/setmode.c
@@ -215,6 +215,7 @@ setmode(p)
mode_t mask;
struct bitcmd *set, *saveset, *endset;
int permXbits, setlen;
+ int equalopdone;
static void compress_mode();
/*
@@ -285,6 +286,8 @@ setmode(p)
free(saveset);
return(NULL);
}
+ if(op == '=')
+ equalopdone = 0;
who &= ~S_ISTXT;
for (perm = 0, permXbits = 0;; ++p) {
@@ -321,10 +324,12 @@ setmode(p)
* to flush out any partial mode that we have,
* and then do the copying of the mode bits.
*/
- if (perm || op == '=') {
+ if (perm) {
ADDCMD(op, who, perm, mask);
perm = 0;
}
+ if (op == '=')
+ equalopdone = 1;
if (op == '+' && permXbits) {
ADDCMD('X', who, permXbits, mask);
permXbits = 0;
@@ -337,7 +342,9 @@ setmode(p)
* Add any permissions that we haven't already
* done.
*/
- if (perm || op == '=') {
+ if (perm || (op == '=' && !equalopdone)) {
+ if(op == '=')
+ equalopdone = 1;
ADDCMD(op, who, perm, mask);
perm = 0;
}
diff --git a/lib/libc/i386/DEFS.h b/lib/libc/i386/DEFS.h
index 4b4df3e68ccb..6df18a13def7 100644
--- a/lib/libc/i386/DEFS.h
+++ b/lib/libc/i386/DEFS.h
@@ -35,7 +35,7 @@
*
* from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90
*
- * $Id: DEFS.h,v 1.3.2.1 1994/05/04 08:44:15 rgrimes Exp $
+ * $Id: DEFS.h,v 1.4 1994/05/03 16:29:13 jkh Exp $
*/
/* XXX should use align 4,0x90 for -m486. */
diff --git a/lib/libc/i386/string/bcmp.S b/lib/libc/i386/string/bcmp.S
index 21027dadd8b4..d19922498d88 100644
--- a/lib/libc/i386/string/bcmp.S
+++ b/lib/libc/i386/string/bcmp.S
@@ -14,7 +14,7 @@
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,11 +27,11 @@
* (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: bcmp.S,v 1.1 1993/12/05 13:01:40 ats Exp $
+ * $Id: bcmp.S,v 1.2 1994/03/31 14:10:57 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: bcmp.S,v 1.1 1993/12/05 13:01:40 ats Exp $"
+ .asciz "$Id: bcmp.S,v 1.2 1994/03/31 14:10:57 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -48,17 +48,16 @@ ENTRY(bcmp)
pushl %esi
movl 12(%esp),%edi
movl 16(%esp),%esi
- movl 20(%esp),%edx
xorl %eax,%eax /* clear return value */
cld /* set compare direction forward */
- movl %edx,%ecx /* compare by words */
+ movl 20(%esp),%ecx /* compare by words */
shrl $2,%ecx
repe
cmpsl
jne L1
- movl %edx,%ecx /* compare remainder by bytes */
+ movl 20(%esp),%ecx /* compare remainder by bytes */
andl $3,%ecx
repe
cmpsb
diff --git a/lib/libc/i386/string/memcmp.S b/lib/libc/i386/string/memcmp.S
index e1fdaaa31f6e..5e74a7373235 100644
--- a/lib/libc/i386/string/memcmp.S
+++ b/lib/libc/i386/string/memcmp.S
@@ -14,7 +14,7 @@
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,11 +27,11 @@
* (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: memcmp.S,v 1.1.2.1 1994/03/07 02:19:34 rgrimes Exp $
+ * $Id: memcmp.S,v 1.3 1994/03/31 14:10:59 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memcmp.S,v 1.1.2.1 1994/03/07 02:19:34 rgrimes Exp $"
+ .asciz "$Id: memcmp.S,v 1.3 1994/03/31 14:10:59 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -48,16 +48,15 @@ ENTRY(memcmp)
pushl %esi
movl 12(%esp),%edi
movl 16(%esp),%esi
- movl 20(%esp),%edx
cld /* set compare direction forward */
- movl %edx,%ecx /* compare by words */
+ movl 20(%esp),%ecx /* compare by words */
shrl $2,%ecx
repe
cmpsl
jne L5 /* do we match so far? */
- movl %edx,%ecx /* compare remainder by bytes */
+ movl 20(%esp),%ecx /* compare remainder by bytes */
andl $3,%ecx
repe
cmpsb
@@ -73,8 +72,8 @@ L5: movl $4,%ecx /* We know that one of the next */
subl %ecx,%esi /* match. */
repe
cmpsb
-L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */
- movzbl -1(%esi),%edx
+L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */
+ movzbl -1(%esi),%edx
subl %edx,%eax
popl %esi
popl %edi
diff --git a/lib/libc/i386/string/memmove.S b/lib/libc/i386/string/memmove.S
index 57e52ad04295..7eeec5bd8c21 100644
--- a/lib/libc/i386/string/memmove.S
+++ b/lib/libc/i386/string/memmove.S
@@ -32,11 +32,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: memmove.S,v 1.1 1993/12/05 13:01:50 ats Exp $
+ * $Id: memmove.S,v 1.2 1994/03/31 14:11:00 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memmove.S,v 1.1 1993/12/05 13:01:50 ats Exp $"
+ .asciz "$Id: memmove.S,v 1.2 1994/03/31 14:11:00 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -51,20 +51,19 @@ ENTRY(memmove)
pushl %esi
pushl %edi
movl 12(%esp),%edi
- pushl %edi
- movl 20(%esp),%esi
- movl 24(%esp),%ecx
+ movl 16(%esp),%esi
+ movl 20(%esp),%ecx
cmpl %esi,%edi /* potentially overlapping? */
jnb 1f
cld /* nope, copy forwards. */
shrl $2,%ecx /* copy by words */
rep
movsl
- movl 24(%esp),%ecx
+ movl 20(%esp),%ecx
andl $3,%ecx /* any bytes left? */
rep
movsb
- popl %eax
+ movl 12(%esp),%eax
popl %edi
popl %esi
ret
@@ -77,13 +76,13 @@ ENTRY(memmove)
decl %esi
rep
movsb
- movl 24(%esp),%ecx /* copy remainder by words */
+ movl 20(%esp),%ecx /* copy remainder by words */
shrl $2,%ecx
subl $3,%esi
subl $3,%edi
rep
movsl
- popl %eax
+ movl 12(%esp),%eax
popl %edi
popl %esi
cld
diff --git a/lib/libc/i386/string/memset.S b/lib/libc/i386/string/memset.S
index 47e763781932..b7fc069da3c5 100644
--- a/lib/libc/i386/string/memset.S
+++ b/lib/libc/i386/string/memset.S
@@ -14,7 +14,7 @@
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,11 +27,11 @@
* (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: memset.S,v 1.1 1993/12/05 13:01:53 ats Exp $
+ * $Id: memset.S,v 1.2 1994/03/31 14:11:01 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memset.S,v 1.1 1993/12/05 13:01:53 ats Exp $"
+ .asciz "$Id: memset.S,v 1.2 1994/03/31 14:11:01 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -57,17 +57,15 @@ ENTRY(memset)
/*
* if the string is too short, it's really not worth the overhead
- * of aligning to word boundries, etc. So we jump to a plain
+ * of aligning to word boundries, etc. So we jump to a plain
* unaligned set.
*/
cmpl $0x0f,%ecx
jle L1
- movl %eax,%edx /* copy value to all bytes in word */
- sall $8,%edx /* XXX is there a better way? */
- orl %edx,%eax
+ movb %al,%ah /* copy char to all bytes in word */
movl %eax,%edx
- sall $16,%edx
+ sall $16,%eax
orl %edx,%eax
movl %edi,%edx /* compute misalignment */
@@ -75,7 +73,7 @@ ENTRY(memset)
andl $3,%edx
movl %ecx,%ebx
subl %edx,%ebx
-
+
movl %edx,%ecx /* set until word aligned */
rep
stosb
diff --git a/lib/libc/i386/string/strcmp.S b/lib/libc/i386/string/strcmp.S
index 015c21aa7fa3..bdc4585aed2f 100644
--- a/lib/libc/i386/string/strcmp.S
+++ b/lib/libc/i386/string/strcmp.S
@@ -27,11 +27,11 @@
* (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: strcmp.S,v 1.1.2.1 1994/03/07 02:19:31 rgrimes Exp $
+ * $Id: strcmp.S,v 1.2 1994/03/04 15:50:28 ache Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strcmp.S,v 1.1.2.1 1994/03/07 02:19:31 rgrimes Exp $"
+ .asciz "$Id: strcmp.S,v 1.2 1994/03/04 15:50:28 ache Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/strncmp.S b/lib/libc/i386/string/strncmp.S
index 72922fb30fec..a4df8025bfb5 100644
--- a/lib/libc/i386/string/strncmp.S
+++ b/lib/libc/i386/string/strncmp.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1993 Winning Strategies, Inc.
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -14,7 +14,7 @@
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,20 +27,20 @@
* (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: strncmp.S,v 1.1.2.1 1994/03/07 02:19:33 rgrimes Exp $
+ * $Id: strncmp.S,v 1.3 1994/03/31 14:11:02 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strncmp.S,v 1.1.2.1 1994/03/07 02:19:33 rgrimes Exp $"
+ .asciz "$Id: strncmp.S,v 1.3 1994/03/31 14:11:02 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
/*
- * strncmp(s1, s2, n)
- * return an integer greater than, equal to, or less than 0,
+ * strncmp(s1, s2, n)
+ * return an integer greater than, equal to, or less than 0,
* according as the first n characters of string s1 is greater
- * than, equal to, or less than the string s2.
+ * than, equal to, or less than the string s2.
*
* %eax - pointer to s1
* %ecx - pointer to s2
@@ -53,7 +53,7 @@
/*
* I've unrolled the loop eight times: large enough to make a
* significant difference, and small enough not to totally trash the
- * cashe.
+ * cache.
*/
ENTRY(strncmp)
@@ -61,92 +61,93 @@ ENTRY(strncmp)
movl 8(%esp),%eax
movl 12(%esp),%ecx
movl 16(%esp),%edx
+ testl %edx,%edx
jmp L2 /* Jump into the loop! */
.align 2,0x90
L1: incl %eax
incl %ecx
decl %edx
-L2: testl %edx,%edx /* Have we compared n chars yet? */
- jle L4 /* Yes, strings are equal */
+L2: jz L4 /* strings are equal */
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
jne L3
+
incl %eax
incl %ecx
decl %edx
- testl %edx,%edx
- jle L4
+ jz L4
movb (%eax),%bl
testb %bl,%bl
- je L3
+ jz L3
cmpb %bl,(%ecx)
je L1
+
.align 2,0x90
-L3: movzbl (%eax),%eax /* unsigned comparision */
- movzbl (%ecx),%ecx
+L3: movzbl (%eax),%eax /* unsigned comparision */
+ movzbl (%ecx),%ecx
subl %ecx,%eax
popl %ebx
ret
diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc
index 855608475d59..aa9d8bb14b56 100644
--- a/lib/libc/locale/Makefile.inc
+++ b/lib/libc/locale/Makefile.inc
@@ -1,6 +1,20 @@
-# @(#)Makefile.inc 5.1 (Berkeley) 2/18/91
+# From: @(#)Makefile.inc 5.1 (Berkeley) 2/18/91
+# $Id: Makefile.inc,v 1.5 1994/04/13 20:12:15 wollman Exp $
# locale sources
.PATH: ${.CURDIR}/${MACHINE}/locale ${.CURDIR}/locale
-SRCS+= lconv.c localeconv.c setlocale.c
+SRCS+= ansi.c frune.c mbrune.c lconv.c localeconv.c rune.c setlocale.c \
+ table.c isctype.c \
+ euc.c none.c utf2.c
+MAN3+= locale/mbrune.3 locale/multibyte.3 locale/rune.3 locale/setlocale.3
+MAN4+= locale/euc.4 locale/utf2.4
+
+MLINKS+= mbrune.3 mbrrune.3 mbrune.3 mbmb.3
+MLINKS+= multibyte.3 mblen.3 multibyte.3 mbstowcs.3 \
+ multibyte.3 mbtowc.3 multibyte.3 wcstombs.3 \
+ multibyte.3 wctomb.3
+MLINKS+= rune.3 setrunelocale.3 rune.3 setinvalidrune.3 \
+ rune.3 sgetrune.3 rune.3 sputrune.3
+MLINKS+= setlocale.3 localeconv.3
+MLINKS+= utf2.4 utf8.4
diff --git a/lib/libc/locale/ansi.c b/lib/libc/locale/ansi.c
new file mode 100644
index 000000000000..e5c8e8ff96de
--- /dev/null
+++ b/lib/libc/locale/ansi.c
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ansi.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <limits.h>
+#include <stddef.h>
+#include <rune.h>
+
+int
+mblen(s, n)
+ const char *s;
+ size_t n;
+{
+ char const *e;
+
+ if (s == 0 || *s == 0)
+ return (0); /* No support for state dependent encodings. */
+
+ if (sgetrune(s, (int)n, &e) == _INVALID_RUNE)
+ return (s - e);
+ return (e - s);
+}
+
+int
+mbtowc(pwc, s, n)
+ wchar_t *pwc;
+ const char *s;
+ size_t n;
+{
+ char const *e;
+ rune_t r;
+
+ if (s == 0 || *s == 0)
+ return (0); /* No support for state dependent encodings. */
+
+ if ((r = sgetrune(s, (int)n, &e)) == _INVALID_RUNE)
+ return (s - e);
+ if (pwc)
+ *pwc = r;
+ return (e - s);
+}
+
+int
+wctomb(s, wchar)
+ char *s;
+ wchar_t wchar;
+{
+ char *e;
+
+ if (s == 0)
+ return (0); /* No support for state dependent encodings. */
+
+ if (wchar == 0) {
+ *s = 0;
+ return (1);
+ }
+
+ sputrune(wchar, s, MB_CUR_MAX, &e);
+ return (e ? e - s : -1);
+}
+
+size_t
+mbstowcs(pwcs, s, n)
+ wchar_t *pwcs;
+ const char *s;
+ size_t n;
+{
+ char const *e;
+ int cnt = 0;
+
+ if (!pwcs || !s)
+ return (-1);
+
+ while (n-- > 0) {
+ *pwcs = sgetrune(s, MB_LEN_MAX, &e);
+ if (*pwcs == _INVALID_RUNE)
+ return (-1);
+ if (*pwcs++ == 0)
+ break;
+ s = e;
+ ++cnt;
+ }
+ return (cnt);
+}
+
+size_t
+wcstombs(s, pwcs, n)
+ char *s;
+ const wchar_t *pwcs;
+ size_t n;
+{
+ char *e;
+ int cnt = 0;
+
+ if (!pwcs || !s)
+ return (-1);
+
+ while (n > 0) {
+ if (*pwcs == 0) {
+ *s = 0;
+ break;
+ }
+ if (!sputrune(*pwcs++, s, (int)n, &e))
+ return (-1); /* encoding error */
+ if (!e) /* too long */
+ return (cnt);
+ cnt += e - s;
+ s = e;
+ }
+ return (cnt);
+}
diff --git a/lib/libc/locale/euc.4 b/lib/libc/locale/euc.4
new file mode 100644
index 000000000000..966b896b657f
--- /dev/null
+++ b/lib/libc/locale/euc.4
@@ -0,0 +1,231 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" 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 the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+.\"
+.\" @(#)euc.4 8.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.Dt EUC 4
+.Os
+.Sh NAME
+.Nm EUC
+.Nd EUC encoding of runes
+.Sh SYNOPSIS
+\fBENCODING "EUC"\fP
+.br
+\fBVARIABLE \fP\fIlen1 mask1 len2 mask2 len3 mask3 len4 mask4 mask\fP
+.Sh DESCRIPTION
+The
+.Nm EUC
+encoding is provided for compatibility with
+.Ux
+based systems.
+See
+.Xr mklocale 1
+for a complete description of the
+.Ev LC_CTYPE
+source file format.
+.Pp
+.Nm EUC
+implements a system of 4 multibyte codesets.
+A multibyte character in the first codeset consists of
+.Ar len1
+bytes starting with a byte in the range of 0x00 to 0x7f.
+To allow use of ASCII,
+.Ar len1
+is always 1.
+A multibyte character in the second codeset consists of
+.Ar len2
+bytes starting with a byte in the range of 0x80-0xff excluding 0x8e and 0x8f.
+A multibyte character in the third codeset consists of
+.Ar len3
+bytes starting with the byte 0x8e.
+A multibyte character in the fourth codeset consists of
+.Ar len4
+bytes starting with the byte 0x8f.
+.Pp
+The
+.Ev rune_t
+encoding of
+.Nm EUC
+multibyte characters is dependent on the
+.Ar len
+and
+.Ar mask
+arguments.
+First, the bytes are moved into a
+.Ev rune_t
+as follows:
+.Bd -literal
+byte0 << ((\fIlen\fPN-1) * 8) | byte1 << ((\fIlen\fPN-2) * 8) | ... | byte\fIlen\fPN-1
+.Ed
+.sp
+The result is then ANDed with
+.Ar ~mask
+and ORed with
+.Ar mask\fPN.
+Codesets 2 and 3 are special in that the leading byte (0x8e or 0x8f) is
+first removed and the
+.Ar len\fPN
+argument is reduced by 1.
+.sp
+For example, the Japanese locale has the following
+.Ev VARIABLE
+line:
+.Bd -literal
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+.Ed
+.sp
+Codeset 1 consists of the values 0x0000 - 0x007f.
+.sp
+Codeset 2 consists of the values who have the bits 0x8080 set.
+.sp
+Codeset 3 consists of the values 0x0080 - 0x00ff.
+.sp
+Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values
+which have the 0x0080 bit set.
+.sp
+Notice that the global
+.Ar mask
+is set to 0x8080, this implies that from those 2 bits the codeset can
+be determined.
+.Sh "EXAMPLE - Japanese Locale"
+This is a complete example of an
+.Ev LC_CTYPE
+source file for the Japanese locale
+.Bd -literal
+/*
+ * Japanese LOCALE_CTYPE definitions using EUC of JIS character sets
+ */
+
+ENCODING "EUC"
+
+/* JIS JIS JIS */
+/* X201 X208 X201 */
+/* 00-7f 84-fe */
+
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+
+/*
+ * Code Set 1
+ */
+ALPHA 'A' - 'Z' 'a' - 'z'
+CONTROL 0x00 - 0x1f 0x7f
+DIGIT '0' - '9'
+GRAPH 0x21 - 0x7e
+LOWER 'a' - 'z'
+PUNCT 0x21 - 0x2f 0x3a - 0x40 0x5b - 0x60 0x7b - 0x7e
+SPACE 0x09 - 0x0d 0x20
+UPPER 'A' - 'Z'
+XDIGIT 'a' - 'f' 'A' - 'F'
+BLANK ' ' '\t'
+PRINT 0x20 - 0x7e
+
+MAPLOWER < 'A' - 'Z' : 'a' > < 'a' - 'z' : 'a' >
+MAPUPPER < 'A' - 'Z' : 'A' > < 'a' - 'z' : 'A' >
+TODIGIT < '0' - '9' : 0 >
+TODIGIT < 'A' - 'F' : 10 > < 'a' - 'f' : 10 >
+
+/*
+ * Code Set 2
+ */
+
+SPACE 0xa1a1
+PHONOGRAM 0xa1bc
+SPECIAL 0xa1a2 - 0xa1fe
+PUNCT 0xa1a2 - 0xa1f8 /* A few too many in here... */
+
+SPECIAL 0xa2a1 - 0xa2ae 0xa2ba - 0xa2c1 0xa2ca - 0xa2d0 0xa2dc - 0xa2ea
+SPECIAL 0xa2f2 - 0xa2f9 0xa2fe
+
+DIGIT 0xa3b0 - 0xa3b9
+UPPER 0xa3c1 - 0xa3da /* Romaji */
+LOWER 0xa3e1 - 0xa3fa /* Romaji */
+MAPLOWER < 0xa3c1 - 0xa3da : 0xa3e1 > /* English */
+MAPLOWER < 0xa3e1 - 0xa3fa : 0xa3e1 > /* English */
+MAPUPPER < 0xa3c1 - 0xa3da : 0xa3c1 >
+MAPUPPER < 0xa3e1 - 0xa3fa : 0xa3c1 >
+
+XDIGIT 0xa3c1 - 0xa3c6 0xa3e1 - 0xa3e6
+
+TODIGIT < 0xa3b0 - 0xa3b9 : 0 >
+TODIGIT < 0xa3c1 - 0xa3c6 : 10 > < 0xa3e1 - 0xa3e6 : 10 >
+
+PHONOGRAM 0xa4a1 - 0xa4f3
+PHONOGRAM 0xa5a1 - 0xa5f6
+
+UPPER 0xa6a1 - 0xa6b8 /* Greek */
+LOWER 0xa6c1 - 0xa6d8 /* Greek */
+MAPLOWER < 0xa6a1 - 0xa6b8 : 0xa6c1 > < 0xa6c1 - 0xa6d8 : 0xa6c1 >
+MAPUPPER < 0xa6a1 - 0xa6b8 : 0xa6a1 > < 0xa6c1 - 0xa6d8 : 0xa6a1 >
+
+UPPER 0xa7a1 - 0xa7c1 /* Cyrillic */
+LOWER 0xa7d1 - 0xa7f1 /* Cyrillic */
+MAPLOWER < 0xa7a1 - 0xa7c1 : 0xa7d1 > < 0xa7d1 - 0xa7f1 : 0xa7d1 >
+MAPUPPER < 0xa7a1 - 0xa7c1 : 0xa7a1 > < 0xa7d1 - 0xa7f1 : 0xa7a1 >
+
+SPECIAL 0xa8a1 - 0xa8c0
+
+IDEOGRAM 0xb0a1 - 0xb0fe 0xb1a1 - 0xb1fe 0xb2a1 - 0xb2fe
+IDEOGRAM 0xb3a1 - 0xb3fe 0xb4a1 - 0xb4fe 0xb5a1 - 0xb5fe
+IDEOGRAM 0xb6a1 - 0xb6fe 0xb7a1 - 0xb7fe 0xb8a1 - 0xb8fe
+IDEOGRAM 0xb9a1 - 0xb9fe 0xbaa1 - 0xbafe 0xbba1 - 0xbbfe
+IDEOGRAM 0xbca1 - 0xbcfe 0xbda1 - 0xbdfe 0xbea1 - 0xbefe
+IDEOGRAM 0xbfa1 - 0xbffe 0xc0a1 - 0xc0fe 0xc1a1 - 0xc1fe
+IDEOGRAM 0xc2a1 - 0xc2fe 0xc3a1 - 0xc3fe 0xc4a1 - 0xc4fe
+IDEOGRAM 0xc5a1 - 0xc5fe 0xc6a1 - 0xc6fe 0xc7a1 - 0xc7fe
+IDEOGRAM 0xc8a1 - 0xc8fe 0xc9a1 - 0xc9fe 0xcaa1 - 0xcafe
+IDEOGRAM 0xcba1 - 0xcbfe 0xcca1 - 0xccfe 0xcda1 - 0xcdfe
+IDEOGRAM 0xcea1 - 0xcefe 0xcfa1 - 0xcfd3 0xd0a1 - 0xd0fe
+IDEOGRAM 0xd1a1 - 0xd1fe 0xd2a1 - 0xd2fe 0xd3a1 - 0xd3fe
+IDEOGRAM 0xd4a1 - 0xd4fe 0xd5a1 - 0xd5fe 0xd6a1 - 0xd6fe
+IDEOGRAM 0xd7a1 - 0xd7fe 0xd8a1 - 0xd8fe 0xd9a1 - 0xd9fe
+IDEOGRAM 0xdaa1 - 0xdafe 0xdba1 - 0xdbfe 0xdca1 - 0xdcfe
+IDEOGRAM 0xdda1 - 0xddfe 0xdea1 - 0xdefe 0xdfa1 - 0xdffe
+IDEOGRAM 0xe0a1 - 0xe0fe 0xe1a1 - 0xe1fe 0xe2a1 - 0xe2fe
+IDEOGRAM 0xe3a1 - 0xe3fe 0xe4a1 - 0xe4fe 0xe5a1 - 0xe5fe
+IDEOGRAM 0xe6a1 - 0xe6fe 0xe7a1 - 0xe7fe 0xe8a1 - 0xe8fe
+IDEOGRAM 0xe9a1 - 0xe9fe 0xeaa1 - 0xeafe 0xeba1 - 0xebfe
+IDEOGRAM 0xeca1 - 0xecfe 0xeda1 - 0xedfe 0xeea1 - 0xeefe
+IDEOGRAM 0xefa1 - 0xeffe 0xf0a1 - 0xf0fe 0xf1a1 - 0xf1fe
+IDEOGRAM 0xf2a1 - 0xf2fe 0xf3a1 - 0xf3fe 0xf4a1 - 0xf4a4
+/*
+ * This is for Code Set 3, half-width kana
+ */
+SPECIAL 0xa1 - 0xdf
+PHONOGRAM 0xa1 - 0xdf
+CONTROL 0x84 - 0x97 0x9b - 0x9f 0xe0 - 0xfe
+.Ed
+.Sh "SEE ALSO"
+.Xr mklocale 1 ,
+.Xr setlocale 3
diff --git a/lib/libc/locale/euc.c b/lib/libc/locale/euc.c
new file mode 100644
index 000000000000..e58c8556087a
--- /dev/null
+++ b/lib/libc/locale/euc.c
@@ -0,0 +1,220 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+rune_t _EUC_sgetrune __P((const char *, size_t, char const **));
+int _EUC_sputrune __P((rune_t, char *, size_t, char **));
+
+typedef struct {
+ int count[4];
+ rune_t bits[4];
+ rune_t mask;
+} _EucInfo;
+
+int
+_EUC_init(rl)
+ _RuneLocale *rl;
+{
+ _EucInfo *ei;
+ int x;
+ char *v, *e;
+
+ rl->sgetrune = _EUC_sgetrune;
+ rl->sputrune = _EUC_sputrune;
+
+ if (!rl->variable) {
+ free(rl);
+ return (EFTYPE);
+ }
+ v = (char *) rl->variable;
+
+ while (*v == ' ' || *v == '\t')
+ ++v;
+
+ if ((ei = malloc(sizeof(_EucInfo))) == NULL) {
+ free(rl);
+ return (ENOMEM);
+ }
+ for (x = 0; x < 4; ++x) {
+ ei->count[x] = (int) strtol(v, &e, 0);
+ if (v == e || !(v = e)) {
+ free(rl);
+ free(ei);
+ return (EFTYPE);
+ }
+ while (*v == ' ' || *v == '\t')
+ ++v;
+ ei->bits[x] = (int) strtol(v, &e, 0);
+ if (v == e || !(v = e)) {
+ free(rl);
+ free(ei);
+ return (EFTYPE);
+ }
+ while (*v == ' ' || *v == '\t')
+ ++v;
+ }
+ ei->mask = (int)strtol(v, &e, 0);
+ if (v == e || !(v = e)) {
+ free(rl);
+ free(ei);
+ return (EFTYPE);
+ }
+ if (sizeof(_EucInfo) <= rl->variable_len) {
+ memcpy(rl->variable, ei, sizeof(_EucInfo));
+ free(ei);
+ } else {
+ rl->variable = &ei;
+ }
+ rl->variable_len = sizeof(_EucInfo);
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 3;
+ return (0);
+}
+
+#define CEI ((_EucInfo *)(_CurrentRuneLocale->variable))
+
+#define _SS2 0x008e
+#define _SS3 0x008f
+
+static inline int
+_euc_set(c)
+ u_int c;
+{
+ c &= 0xff;
+
+ return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0);
+}
+rune_t
+_EUC_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ rune_t rune = 0;
+ int len, set;
+
+ if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) {
+ if (result)
+ *result = string;
+ return (_INVALID_RUNE);
+ }
+ switch (set) {
+ case 3:
+ case 2:
+ --len;
+ ++string;
+ /* FALLTHROUGH */
+ case 1:
+ case 0:
+ while (len-- > 0)
+ rune = (rune << 8) | ((u_int)(*string++) & 0xff);
+ break;
+ }
+ if (result)
+ *result = string;
+ return ((rune & ~CEI->mask) | CEI->bits[set]);
+}
+
+int
+_EUC_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ rune_t m = c & CEI->mask;
+ rune_t nm = c & ~m;
+ int i, len;
+
+ if (m == CEI->bits[1]) {
+CodeSet1:
+ /* Codeset 1: The first byte must have 0x80 in it. */
+ i = len = CEI->count[1];
+ if (n >= len) {
+ if (result)
+ *result = string + len;
+ while (i-- > 0)
+ *string++ = (nm >> (i << 3)) | 0x80;
+ } else
+ if (result)
+ *result = (char *) 0;
+ } else {
+ if (m == CEI->bits[0]) {
+ i = len = CEI->count[0];
+ if (n < len) {
+ if (result)
+ *result = NULL;
+ return (len);
+ }
+ } else
+ if (m == CEI->bits[2]) {
+ i = len = CEI->count[2];
+ if (n < len) {
+ if (result)
+ *result = NULL;
+ return (len);
+ }
+ *string++ = _SS2;
+ --i;
+ } else
+ if (m == CEI->bits[3]) {
+ i = len = CEI->count[3];
+ if (n < len) {
+ if (result)
+ *result = NULL;
+ return (len);
+ }
+ *string++ = _SS3;
+ --i;
+ } else
+ goto CodeSet1; /* Bletch */
+ while (i-- > 0)
+ *string++ = (nm >> (i << 3)) & 0xff;
+ if (result)
+ *result = string;
+ }
+ return (len);
+}
diff --git a/lib/libc/locale/frune.c b/lib/libc/locale/frune.c
new file mode 100644
index 000000000000..443d3ba6eb36
--- /dev/null
+++ b/lib/libc/locale/frune.c
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)frune.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+
+long
+fgetrune(fp)
+ FILE *fp;
+{
+ rune_t r;
+ int c, len;
+ char buf[MB_LEN_MAX];
+ char const *result;
+
+ len = 0;
+ do {
+ if ((c = getc(fp)) == EOF) {
+ if (len)
+ break;
+ return (EOF);
+ }
+ buf[len++] = c;
+
+ if ((r = sgetrune(buf, len, &result)) != _INVALID_RUNE)
+ return (r);
+ } while (result == buf && len < MB_LEN_MAX);
+
+ while (--len > 0)
+ ungetc(buf[len], fp);
+ return (_INVALID_RUNE);
+}
+
+int
+fungetrune(r, fp)
+ rune_t r;
+ FILE* fp;
+{
+ int len;
+ char buf[MB_LEN_MAX];
+
+ len = sputrune(r, buf, MB_LEN_MAX, 0);
+ while (len-- > 0)
+ if (ungetc(buf[len], fp) == EOF)
+ return (EOF);
+ return (0);
+}
+
+int
+fputrune(r, fp)
+ rune_t r;
+ FILE *fp;
+{
+ int i, len;
+ char buf[MB_LEN_MAX];
+
+ len = sputrune(r, buf, MB_LEN_MAX, 0);
+
+ for (i = 0; i < len; ++i)
+ if (putc(buf[i], fp) == EOF)
+ return (EOF);
+
+ return (0);
+}
diff --git a/lib/libc/gen/isctype.c b/lib/libc/locale/isctype.c
index d8dd5bc33e9f..06cb1254ce68 100644
--- a/lib/libc/gen/isctype.c
+++ b/lib/libc/locale/isctype.c
@@ -1,15 +1,9 @@
/*
- * Copyright (c) UNIX System Laboratories, Inc. All or some portions
- * of this file are derived from material licensed to the
- * University of California by American Telephone and Telegraph Co.
- * or UNIX System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
- * $Id: isctype.c,v 1.1.1.1.2.1 1994/05/04 07:39:44 rgrimes Exp $
- */
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,105 +32,139 @@
* 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(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)isctype.c 5.2 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)isctype.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#define _ANSI_LIBRARY
#include <ctype.h>
#undef isalnum
+int
isalnum(c)
int c;
{
- return((_ctype_ + 1)[c] & (_U|_L|_N));
+ return(__istype((c), (_A|_D)));
}
#undef isalpha
+int
isalpha(c)
int c;
{
- return((_ctype_ + 1)[c] & (_U|_L));
+ return (__istype((c), _A));
+}
+
+#undef isascii
+int
+isascii(c)
+ int c;
+{
+ return((c & ~0x7F) == 0);
+}
+
+#undef isblank
+int
+isblank(c)
+ int c;
+{
+ return (__istype((c), _B));
}
#undef iscntrl
+int
iscntrl(c)
int c;
{
- return((_ctype_ + 1)[c] & _C);
+ return (__istype((c), _C));
}
#undef isdigit
+int
isdigit(c)
int c;
{
- return((_ctype_ + 1)[c] & _N);
+ return (__isctype((c), _D));
}
#undef isgraph
+int
isgraph(c)
int c;
{
- return((_ctype_ + 1)[c] & (_P|_U|_L|_N));
+ return (__istype((c), _G));
}
#undef islower
+int
islower(c)
int c;
{
- return((_ctype_ + 1)[c] & _L);
+ return (__istype((c), _L));
}
#undef isprint
+int
isprint(c)
int c;
{
- return((_ctype_ + 1)[c] & (_P|_U|_L|_N|_B));
+ return (__istype((c), _R));
}
#undef ispunct
+int
ispunct(c)
int c;
{
- return((_ctype_ + 1)[c] & _P);
+ return (__istype((c), _P));
}
#undef isspace
+int
isspace(c)
int c;
{
- return((_ctype_ + 1)[c] & _S);
+ return (__istype((c), _S));
}
#undef isupper
+int
isupper(c)
int c;
{
- return((_ctype_ + 1)[c] & _U);
+ return (__istype((c), _U));
}
#undef isxdigit
+int
isxdigit(c)
int c;
{
- return((_ctype_ + 1)[c] & (_N|_X));
+ return (__isctype((c), _X));
}
-#undef tolower
-tolower(c)
+#undef toascii
+int
+toascii(c)
int c;
{
-/* was: return((c) - 'A' + 'a');*/
- return ( isupper(c) ? c - 'A' + 'a' : c);
+ return (c & 0177);
}
#undef toupper
+int
toupper(c)
int c;
{
-/* was: return((c) - 'a' + 'A');*/
- return ( islower(c) ? c - 'a' + 'A' : c);
+ return((c & _CRMASK) ? ___toupper(c) : _CurrentRuneLocale->mapupper[c]);
+}
+
+#undef tolower
+int
+tolower(c)
+ int c;
+{
+ return((c & _CRMASK) ? ___tolower(c) : _CurrentRuneLocale->maplower[c]);
}
diff --git a/lib/libc/locale/mbrune.3 b/lib/libc/locale/mbrune.3
new file mode 100644
index 000000000000..83e9dfe938d2
--- /dev/null
+++ b/lib/libc/locale/mbrune.3
@@ -0,0 +1,157 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" 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 the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+.\"
+.\" @(#)mbrune.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.Dt MBRUNE 3
+.Os
+.Sh NAME
+.Nm mbrune ,
+.Nm mbrrune ,
+.Nm mbmb
+.Nd multibyte rune support for C
+.Sh SYNOPSIS
+.Fd #include <rune.h>
+.Ft char *
+.Fn mbrune "const char *string" "rune_t rune"
+.Ft char *
+.Fn mbrrune "const char *string" "rune_t rune"
+.Ft char *
+.Fn mbmb "const char *string" "char *pattern"
+.Sh DESCRIPTION
+These routines provide the corresponding functionality of
+.Fn strchr ,
+.Fn strrchr
+and
+.Fn strstr
+for multibyte strings.
+.Pp
+The
+.Fn mbrune
+function locates the first occurrence of
+.Fn rune
+in the string pointed to by
+.Ar string .
+The terminating
+.Dv NULL
+character is considered part of the string.
+If
+.Fa rune
+is
+.Ql \e0 ,
+.Fn mbrune
+locates the terminating
+.Ql \e0 .
+.Pp
+The
+.Fn mbrrune
+function
+locates the last occurrence of
+.Fa rune
+in the string
+.Fa string .
+If
+.Fa rune
+is
+.Ql \e0 ,
+.Fn mbrune
+locates the terminating
+.Ql \e0 .
+.Pp
+The
+.Fn mbmb
+function locates the first occurrence of the null-terminated string
+.Fa pattern
+in the null-terminated string
+.Fa string.
+If
+.Fa pattern
+is the empty string,
+.Fn mbmb
+returns
+.Fa string ;
+if
+.Fa pattern
+occurs nowhere in
+.Fa string ,
+.Fn mbmb
+returns
+.Dv NULL ;
+otherwise
+.Fn mbmb
+returns a pointer to the first character of the first occurrence of
+.Fa pattern .
+.Sh RETURN VALUES
+The function
+.Fn mbrune
+returns a pointer to the located character, or
+.Dv NULL
+if the character does not appear in the string.
+.Pp
+The
+.Fn mbrrune
+function
+returns a pointer to the character, or
+.Dv NULL
+if the character does not appear in the string.
+.Pp
+The
+.Fn mbmb
+function
+returns a pointer to the
+.Fa pattern ,
+or
+.Dv NULL
+if the
+.Fa pattern
+does not appear in the string.
+.Sh "SEE ALSO
+.Xr euc 4 ,
+.Xr mbrune 3 ,
+.Xr rune 3 ,
+.Xr setlocale 3 ,
+.Xr utf2 4
+.Sh HISTORY
+The
+.Fn mbrune ,
+.Fn mbrrune ,
+and
+.Fn mbmb
+functions
+first appeared in Plan 9 from Bell Labs as
+.Fn utfrune ,
+.Fn utfrrune ,
+and
+.Fn utfutf .
diff --git a/lib/libc/locale/mbrune.c b/lib/libc/locale/mbrune.c
new file mode 100644
index 000000000000..92efe838a036
--- /dev/null
+++ b/lib/libc/locale/mbrune.c
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mbrune.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <rune.h>
+#include <stddef.h>
+#include <string.h>
+
+char *
+mbrune(string, c)
+ const char *string;
+ rune_t c;
+{
+ char const *result;
+ rune_t r;
+
+ while ((r = sgetrune(string, MB_LEN_MAX, &result))) {
+ if (r == c)
+ return ((char *)string);
+ string = result == string ? string + 1 : result;
+ }
+
+ return (c == *string ? (char *)string : NULL);
+}
+
+char *
+mbrrune(string, c)
+ const char *string;
+ rune_t c;
+{
+ const char *last = 0;
+ char const *result;
+ rune_t r;
+
+ while ((r = sgetrune(string, MB_LEN_MAX, &result))) {
+ if (r == c)
+ last = string;
+ string = result == string ? string + 1 : result;
+ }
+ return (c == *string ? (char *)string : (char *)last);
+}
+
+char *
+mbmb(string, pattern)
+ const char *string;
+ char *pattern;
+{
+ rune_t first, r;
+ size_t plen, slen;
+ char const *result;
+
+ plen = strlen(pattern);
+ slen = strlen(string);
+ if (plen > slen)
+ return (0);
+
+ first = sgetrune(pattern, plen, &result);
+ if (result == string)
+ return (0);
+
+ while (slen >= plen && (r = sgetrune(string, slen, &result))) {
+ if (r == first) {
+ if (strncmp(string, pattern, slen) == 0)
+ return ((char *) string);
+ }
+ if (result == string) {
+ --slen;
+ ++string;
+ } else {
+ slen -= result - string;
+ string = result;
+ }
+ }
+ return (0);
+}
diff --git a/lib/libc/locale/multibyte.3 b/lib/libc/locale/multibyte.3
new file mode 100644
index 000000000000..3ea10e5ace3d
--- /dev/null
+++ b/lib/libc/locale/multibyte.3
@@ -0,0 +1,241 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley of BSDI.
+.\"
+.\" 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 the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+.\"
+.\" @(#)multibyte.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.Dt MULTIBYTE 3
+.Os
+.Sh NAME
+.Nm mblen ,
+.Nm mbstowcs ,
+.Nm mbtowc ,
+.Nm wcstombs ,
+.Nm wctomb
+.Nd multibyte character support for C
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn mblen "const char *mbchar" "int nbytes"
+.Ft size_t
+.Fn mbstowcs "wchar_t *wcstring" "const char *mbstring" "size_t nwchars"
+.Ft int
+.Fn mbtowc "wchar_t *wcharp" "const char *mbchar" "size_t nbytes"
+.Ft size_t
+.Fn wcstombs "char *mbstring" "const wchar_t *wcstring" "size_t nbytes"
+.Ft int
+.Fn wctomb "char *mbchar" "wchar_t wchar"
+.Sh DESCRIPTION
+The basic elements of some written natural languages such as Chinese
+cannot be represented uniquely with single C
+.Va char Ns s .
+The C standard supports two different ways of dealing with
+extended natural language encodings,
+.Em wide
+characters and
+.Em multibyte
+characters.
+Wide characters are an internal representation
+which allows each basic element to map
+to a single object of type
+.Va wchar_t .
+Multibyte characters are used for input and output
+and code each basic element as a sequence of C
+.Va char Ns s .
+Individual basic elements may map into one or more
+.Pq up to Dv MB_CHAR_MAX
+bytes in a multibyte character.
+.Pp
+The current locale
+.Pq Xr setlocale 3
+governs the interpretation of wide and multibyte characters.
+The locale category
+.Dv LC_CTYPE
+specifically controls this interpretation.
+The
+.Va wchar_t
+type is wide enough to hold the largest value
+in the wide character representations for all locales.
+.Pp
+Multibyte strings may contain
+.Sq shift
+indicators to switch to and from
+particular modes within the given representation.
+If explicit bytes are used to signal shifting,
+these are not recognized as separate characters
+but are lumped with a neighboring character.
+There is always a distinguished
+.Sq initial
+shift state.
+The
+.Fn mbstowcs
+and
+.Fn wcstombs
+functions assume that multibyte strings are interpreted
+starting from the initial shift state.
+The
+.Fn mblen ,
+.Fn mbtowc
+and
+.Fn wctomb
+functions maintain static shift state internally.
+A call with a null
+.Fa mbchar
+pointer returns nonzero if the current locale requires shift states,
+zero otherwise;
+if shift states are required, the shift state is reset to the initial state.
+The internal shift states are undefined after a call to
+.Fn setlocale
+with the
+.Dv LC_CTYPE
+or
+.Dv LC_ALL
+categories.
+.Pp
+For convenience in processing,
+the wide character with value 0
+.Pq the null wide character
+is recognized as the wide character string terminator,
+and the character with value 0
+.Pq the null byte
+is recognized as the multibyte character string terminator.
+Null bytes are not permitted within multibyte characters.
+.Pp
+The
+.Fn mblen
+function computes the length in bytes
+of a multibyte character
+.Fa mbchar .
+Up to
+.Fa nbytes
+bytes are examined.
+.Pp
+The
+.Fn mbtowc
+function converts a multibyte character
+.Fa mbchar
+into a wide character and stores the result
+in the object pointed to by
+.Fa wcharp.
+Up to
+.Fa nbytes
+bytes are examined.
+.Pp
+The
+.Fn wctomb
+function converts a wide character
+.Fa wchar
+into a multibyte character and stores
+the result in
+.Fa mbchar .
+The object pointed to by
+.Fa mbchar
+must be large enough to accommodate the multibyte character.
+.Pp
+The
+.Fn mbstowcs
+function converts a multibyte character string
+.Fa mbstring
+into a wide character string
+.Fa wcstring .
+No more than
+.Fa nwchars
+wide characters are stored.
+A terminating null wide character is appended if there is room.
+.Pp
+The
+.Fn wcstombs
+function converts a wide character string
+.Fa wcstring
+into a multibyte character string
+.Fa mbstring .
+Up to
+.Fa nbytes
+bytes are stored in
+.Fa mbstring .
+Partial multibyte characters at the end of the string are not stored.
+The multibyte character string is null terminated if there is room.
+.Sh "RETURN VALUES
+If multibyte characters are not supported in the current locale,
+all of these functions will return \-1 if characters can be processed,
+otherwise 0.
+.Pp
+If
+.Fa mbchar
+is
+.Dv NULL ,
+the
+.Fn mblen ,
+.Fn mbtowc
+and
+.Fn wctomb
+functions return nonzero if shift states are supported,
+zero otherwise.
+If
+.Fa mbchar
+is valid,
+then these functions return
+the number of bytes processed in
+.Fa mbchar ,
+or \-1 if no multibyte character
+could be recognized or converted.
+.Pp
+The
+.Fn mbstowcs
+function returns the number of wide characters converted,
+not counting any terminating null wide character.
+The
+.Fn wcstombs
+function returns the number of bytes converted,
+not counting any terminating null byte.
+If any invalid multibyte characters are encountered,
+both functions return \-1.
+.Sh "SEE ALSO
+.Xr euc 4 ,
+.Xr mbrune 3 ,
+.Xr rune 3 ,
+.Xr setlocale 3 ,
+.Xr utf2 4
+.Sh STANDARDS
+The
+.Fn mblen ,
+.Fn mbstowcs ,
+.Fn mbtowc ,
+.Fn wcstombs
+and
+.Fn wctomb
+functions conform to
+.St -ansiC .
+.Sh BUGS
+The current implementation does not support shift states.
diff --git a/lib/libc/stdlib/multibyte.c b/lib/libc/locale/none.c
index 695127969633..b5d8e44299cd 100644
--- a/lib/libc/stdlib/multibyte.c
+++ b/lib/libc/locale/none.c
@@ -1,6 +1,9 @@
-/*
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,74 +35,59 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)multibyte.c 5.1 (Berkeley) 2/18/91";
+static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
+#include <stddef.h>
+#include <stdio.h>
+#include <rune.h>
+#include <errno.h>
#include <stdlib.h>
-/*
- * Stub multibyte character functions.
- * These ignore the current fixed ("C") locale and
- * always indicate that no multibyte characters are supported.
- */
+rune_t _none_sgetrune __P((const char *, size_t, char const **));
+int _none_sputrune __P((rune_t, char *, size_t, char **));
int
-mblen(s, n)
- const char *s;
- size_t n;
+_none_init(rl)
+ _RuneLocale *rl;
{
- if (s && n && *s)
- return -1;
- return 0;
+ rl->sgetrune = _none_sgetrune;
+ rl->sputrune = _none_sputrune;
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 1;
+ return(0);
}
-/*ARGSUSED*/
-int
-mbtowc(pwc, s, n)
- wchar_t *pwc;
- const char *s;
+rune_t
+_none_sgetrune(string, n, result)
+ const char *string;
size_t n;
+ char const **result;
{
- if (s && n && *s)
- return -1;
- return 0;
-}
-
-/*ARGSUSED*/
-int
-#ifdef __STDC__
-wctomb(char *s, wchar_t wchar)
-#else
-wctomb(s, wchar)
- char *s;
- wchar_t wchar;
-#endif
-{
- if (s)
- return -1;
- return 0;
-}
+ int c;
-/*ARGSUSED*/
-size_t
-mbstowcs(pwcs, s, n)
- wchar_t *pwcs;
- const char *s;
- size_t n;
-{
- if (s && n && *s)
- return -1;
- return 0;
+ if (n < 1) {
+ if (result)
+ *result = string;
+ return(_INVALID_RUNE);
+ }
+ if (result)
+ *result = string + 1;
+ return(*string & 0xff);
}
-/*ARGSUSED*/
-size_t
-wcstombs(s, pwcs, n)
- char *s;
- const wchar_t *pwcs;
+int
+_none_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
size_t n;
{
- if (pwcs && n && *pwcs)
- return -1;
- return 0;
+ if (n >= 1) {
+ if (string)
+ *string = c;
+ if (result)
+ *result = string + 1;
+ } else if (result)
+ *result = (char *)0;
+ return(1);
}
diff --git a/lib/libc/locale/rune.3 b/lib/libc/locale/rune.3
new file mode 100644
index 000000000000..8d2ca5dd4b5e
--- /dev/null
+++ b/lib/libc/locale/rune.3
@@ -0,0 +1,269 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" 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 the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+.\"
+.\" @(#)rune.3 8.1 (Berkeley) 6/27/93
+.\"
+.Dd "June 27, 1993"
+.Dt RUNE 3
+.Os
+.Sh NAME
+.Nm setrunelocale ,
+.Nm setinvalidrune ,
+.Nm sgetrune ,
+.Nm sputrune
+.Nd rune support for C
+.Sh SYNOPSIS
+.Fd #include <rune.h>
+.Fd #include <errno.h>
+.Ft int
+.Fn setrunelocale "char *locale"
+.Ft void
+.Fn setinvalidrune "rune_t rune"
+.Ft rune_t
+.Fn sgetrune "const char *string" "size_t n" "char const **result"
+.Ft int
+.Fn sputrune "rune_t rune" "char *string" "size_t n" "char **result"
+.sp
+.Fd #include <stdio.h>
+.Ft long
+.Fn fgetrune "FILE *stream"
+.Ft int
+.Fn fungetrune "rune_t rune" "FILE *stream"
+.Ft int
+.Fn fputrune "rune_t rune" "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn setrunelocale
+controls the type of encoding used to represent runes as multibyte strings
+as well as the properties of the runes as defined in
+\fB<ctype.h>\fP.
+The
+.Fa locale
+argument indicates the locale which to load.
+If the locale is successfully loaded,
+.Dv 0
+is returned, otherwise an errno value is returned to indicate the
+type of error.
+.Pp
+The
+.Fn setinvalidrune
+function sets the value of the global value
+.Ev _INVALID_RUNE
+to be
+.Fa rune.
+.Pp
+The
+.Fn sgetrune
+function tries to read a single multibyte character from
+.Fa string ,
+which is at most
+.Fa n
+bytes long.
+If
+.Fn sgetrune
+is successful, the rune is returned.
+If
+.Fa result
+is not
+.Dv NULL ,
+.Fa *result
+will point to the first byte which was not converted in
+.Fa string.
+If the first
+.Fa n
+bytes of
+.Fa string
+do not describe a full multibyte character,
+.Ev _INVALID_RUNE
+is returned and
+.Fa *result
+will point to
+.Fa string.
+If there is an encoding error at the start of
+.Fa string ,
+.Ev _INVALID_RUNE
+is returned and
+.Fa *result
+will point to the second character of
+.Fa string.
+.Pp
+the
+.Fn sputrune
+function tries to encode
+.Fa rune
+as a multibyte string and store it at
+.Fa string ,
+but no more than
+.Fa n
+bytes will be stored.
+If
+.Fa result
+is not
+.Dv NULL ,
+.Fa *result
+will be set to point to the first byte in string following the new
+multibyte character.
+If
+.Fa string
+is
+.Dv NULL ,
+.Fa *result
+will point to
+.Dv "(char *)0 +"
+.Fa x ,
+where
+.Fa x
+is the number of bytes that would be needed to store the multibyte value.
+If the multibyte character would consist of more than
+.Fa n
+bytes and
+.Fa result
+is not
+.Dv NULL ,
+.Fa *result
+will be set to
+.Dv NULL.
+In all cases,
+.Fn sputrune
+will return the number of bytes which would be needed to store
+.Fa rune
+as a multibyte character.
+.Pp
+The
+.Fn fgetrune
+function operates the same as
+.Fn sgetrune
+with the exception that it attempts to read enough bytes from
+.Fa stream
+to decode a single rune. It returns either
+.Ev EOF
+on end of file,
+.Ev _INVALID_RUNE
+on an encoding error, or the rune decoded if all went well.
+.Pp
+The
+.Fn fungetrune
+function function pushes the multibyte encoding, as provided by
+.Fn sputrune ,
+of
+.Fa rune
+onto
+.Fa stream
+such that the next
+.Fn fgetrune
+call will return
+.Fa rune .
+It returns
+.Ev EOF
+if it fails and
+.Dv 0
+on success.
+.Pp
+The
+.Fn fputrune
+function writes the multibyte encoding of
+.Fa rune ,
+as provided by
+.Fn sputrune ,
+onto
+.Fa stream .
+It returns
+.Ev EOF
+on failure and
+.Dv 0
+on success.
+.Sh RETURN VALUES
+The
+.Fn setrunelocale
+function returns one of the following values:
+.Bl -tag -width WWWWWWWW
+.It Dv 0
+.Fa setrunelocale was successful.
+.It Ev EFAULT
+.Fa locale
+was
+.Dv NULL .
+.It Ev ENOENT
+The locale could not be found.
+.It Ev EFTYPE
+The file found was not a valid file.
+.It Ev EINVAL
+The encoding indicated by the locale was unknown.
+.El
+.Pp
+The
+.Fn sgetrune
+function either returns the rune read or
+.Ev _INVALID_RUNE .
+The
+.Fn sputrune
+function returns the number of bytes needed to store
+.Fa rune
+as a multibyte string.
+.Sh FILES
+.Bl -tag -width /usr/share/locale/locale/LC_CTYPE -compact
+.It Pa $PATH_LOCALE/\fIlocale\fP/LC_CTYPE
+.It Pa /usr/share/locale/\fIlocale\fP/LC_CTYPE
+binary LC_CTYPE file for the locale \fIlocale\fP.
+.El
+.Sh "SEE ALSO
+.Xr euc 4 ,
+.Xr mbrune 3 ,
+.Xr setlocale 3 ,
+.Xr utf2 4
+.Sh NOTE
+The ANSI C type
+.Ev wchar_t
+is the same as
+.Ev rune_t .
+.Ev Rune_t
+was chosen to accent the purposeful choice of not basing the
+system with the ANSI C
+primitives, which were, shall we say, less aesthetic.
+.Sh HISTORY
+These functions first appeared in
+.Bx 4.4 .
+.Pp
+The
+.Fn setrunelocale
+function and the other non-ANSI rune functions were inspired by
+.Nm Plan 9 from Bell Labs
+as a much more sane alternative to the ANSI multibyte and
+wide character support.
+.\"They were conceived at the San Diego 1993 Summer USENIX conference by
+.\"Paul Borman of Krystal Technologies, Keith Bostic of CSRG and Andrew Hume
+.\"of Bell Labs.
+.Pp
+All of the ANSI multibyte and wide character
+support functions are built using the rune functions.
diff --git a/lib/libc/locale/rune.c b/lib/libc/locale/rune.c
new file mode 100644
index 000000000000..b239484fac81
--- /dev/null
+++ b/lib/libc/locale/rune.c
@@ -0,0 +1,334 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <rune.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int _none_init __P((_RuneLocale *));
+extern int _UTF2_init __P((_RuneLocale *));
+extern int _EUC_init __P((_RuneLocale *));
+static _RuneLocale *_Read_RuneMagi __P((FILE *));
+
+static char *PathLocale = 0;
+
+int
+setrunelocale(encoding)
+ char *encoding;
+{
+ FILE *fp;
+ char name[PATH_MAX];
+ _RuneLocale *rl;
+
+ if (!encoding)
+ return(EFAULT);
+
+ /*
+ * The "C" and "POSIX" locale are always here.
+ */
+ if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) {
+ _CurrentRuneLocale = &_DefaultRuneLocale;
+ return(0);
+ }
+
+ if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE")))
+ PathLocale = _PATH_LOCALE;
+
+ sprintf(name, "%s/%s/LC_CTYPE", PathLocale, encoding);
+
+ if ((fp = fopen(name, "r")) == NULL)
+ return(ENOENT);
+
+ if ((rl = _Read_RuneMagi(fp)) == 0) {
+ fclose(fp);
+ return(EFTYPE);
+ }
+
+ if (!rl->encoding[0] || !strcmp(rl->encoding, "UTF2")) {
+ return(_UTF2_init(rl));
+ } else if (!strcmp(rl->encoding, "NONE")) {
+ return(_none_init(rl));
+ } else if (!strcmp(rl->encoding, "EUC")) {
+ return(_EUC_init(rl));
+ } else
+ return(EINVAL);
+}
+
+void
+setinvalidrune(ir)
+ rune_t ir;
+{
+ _INVALID_RUNE = ir;
+}
+
+static _RuneLocale *
+_Read_RuneMagi(fp)
+ FILE *fp;
+{
+ char *data;
+ void *np;
+ void *lastp;
+ _RuneLocale *rl;
+ _RuneEntry *rr;
+ struct stat sb;
+ int x;
+
+ if (fstat(fileno(fp), &sb) < 0)
+ return(0);
+
+ if (sb.st_size < sizeof(_RuneLocale))
+ return(0);
+
+ if ((data = malloc(sb.st_size)) == NULL)
+ return(0);
+
+ rewind(fp); /* Someone might have read the magic number once already */
+
+ if (fread(data, sb.st_size, 1, fp) != 1) {
+ free(data);
+ return(0);
+ }
+
+ rl = (_RuneLocale *)data;
+ lastp = data + sb.st_size;
+
+ rl->variable = rl + 1;
+
+ if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
+ free(data);
+ return(0);
+ }
+
+ rl->invalid_rune = ntohl(rl->invalid_rune);
+ rl->variable_len = ntohl(rl->variable_len);
+ rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
+ rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
+ rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
+
+ for (x = 0; x < _CACHED_RUNES; ++x) {
+ rl->runetype[x] = ntohl(rl->runetype[x]);
+ rl->maplower[x] = ntohl(rl->maplower[x]);
+ rl->mapupper[x] = ntohl(rl->mapupper[x]);
+ }
+
+ rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
+ rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+
+ rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
+ rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+
+ rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
+ rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+
+ for (x = 0; x < rl->runetype_ext.nranges; ++x) {
+ rr = rl->runetype_ext.ranges;
+
+ rr[x].min = ntohl(rr[x].min);
+ rr[x].max = ntohl(rr[x].max);
+ if ((rr[x].map = ntohl(rr[x].map)) == 0) {
+ int len = rr[x].max - rr[x].min + 1;
+ rr[x].types = rl->variable;
+ rl->variable = rr[x].types + len;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+ while (len-- > 0)
+ rr[x].types[len] = ntohl(rr[x].types[len]);
+ } else
+ rr[x].types = 0;
+ }
+
+ for (x = 0; x < rl->maplower_ext.nranges; ++x) {
+ rr = rl->maplower_ext.ranges;
+
+ rr[x].min = ntohl(rr[x].min);
+ rr[x].max = ntohl(rr[x].max);
+ rr[x].map = ntohl(rr[x].map);
+ }
+
+ for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
+ rr = rl->mapupper_ext.ranges;
+
+ rr[x].min = ntohl(rr[x].min);
+ rr[x].max = ntohl(rr[x].max);
+ rr[x].map = ntohl(rr[x].map);
+ }
+ if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
+ free(data);
+ return(0);
+ }
+
+ /*
+ * Go out and zero pointers that should be zero.
+ */
+ if (!rl->variable_len)
+ rl->variable = 0;
+
+ if (!rl->runetype_ext.nranges)
+ rl->runetype_ext.ranges = 0;
+
+ if (!rl->maplower_ext.nranges)
+ rl->maplower_ext.ranges = 0;
+
+ if (!rl->mapupper_ext.nranges)
+ rl->mapupper_ext.ranges = 0;
+
+ return(rl);
+}
+
+unsigned long
+___runetype(c)
+ _BSD_RUNE_T_ c;
+{
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->runetype_ext;
+ _RuneEntry *re = rr->ranges;
+
+ if (c == EOF)
+ return(0);
+ for (x = 0; x < rr->nranges; ++x, ++re) {
+ if (c < re->min)
+ return(0L);
+ if (c <= re->max) {
+ if (re->types)
+ return(re->types[c - re->min]);
+ else
+ return(re->map);
+ }
+ }
+ return(0L);
+}
+
+_BSD_RUNE_T_
+___toupper(c)
+ _BSD_RUNE_T_ c;
+{
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
+ _RuneEntry *re = rr->ranges;
+
+ if (c == EOF)
+ return(EOF);
+ for (x = 0; x < rr->nranges; ++x, ++re) {
+ if (c < re->min)
+ return(c);
+ if (c <= re->max)
+ return(re->map + c - re->min);
+ }
+ return(c);
+}
+
+_BSD_RUNE_T_
+___tolower(c)
+ _BSD_RUNE_T_ c;
+{
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->maplower_ext;
+ _RuneEntry *re = rr->ranges;
+
+ if (c == EOF)
+ return(EOF);
+ for (x = 0; x < rr->nranges; ++x, ++re) {
+ if (c < re->min)
+ return(c);
+ if (c <= re->max)
+ return(re->map + c - re->min);
+ }
+ return(c);
+}
+
+
+#if !defined(_USE_CTYPE_INLINE_) && !defined(_USE_CTYPE_MACROS_)
+/*
+ * See comments in <machine/ansi.h>
+ */
+int
+__istype(c, f)
+ _BSD_RUNE_T_ c;
+ unsigned long f;
+{
+ return ((((c & _CRMASK) ? ___runetype(c)
+ : _CurrentRuneLocale->runetype[c]) & f) ? 1 : 0);
+}
+
+int
+__isctype(_BSD_RUNE_T_ c, unsigned long f)
+ _BSD_RUNE_T_ c;
+ unsigned long f;
+{
+ return ((((c & _CRMASK) ? 0
+ : _DefaultRuneLocale.runetype[c]) & f) ? 1 : 0);
+}
+
+_BSD_RUNE_T_
+toupper(c)
+ _BSD_RUNE_T_ c;
+{
+ return ((c & _CRMASK) ?
+ ___toupper(c) : _CurrentRuneLocale->mapupper[c]);
+}
+
+_BSD_RUNE_T_
+tolower(c)
+ _BSD_RUNE_T_ c;
+{
+ return ((c & _CRMASK) ?
+ ___tolower(c) : _CurrentRuneLocale->maplower[c]);
+}
+#endif
diff --git a/lib/libc/locale/setlocale.3 b/lib/libc/locale/setlocale.3
new file mode 100644
index 000000000000..74cce03bfc5e
--- /dev/null
+++ b/lib/libc/locale/setlocale.3
@@ -0,0 +1,321 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley at BSDI.
+.\"
+.\" 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 the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+.\"
+.\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.Dt SETLOCALE 3
+.Os
+.Sh NAME
+.Nm setlocale ,
+.Nm localeconv
+.Nd natural language formatting for C
+.Sh SYNOPSIS
+.Fd #include <locale.h>
+.Ft char *
+.Fn setlocale "int category" "const char *locale"
+.Ft struct lconv *
+.Fn localeconv "void"
+.Sh DESCRIPTION
+The
+.Fn setlocale
+function sets the C library's notion
+of natural language formatting style
+for particular sets of routines.
+Each such style is called a
+.Sq locale
+and is invoked using an appropriate name passed as a C string.
+The
+.Fn localeconv
+routine returns the current locale's parameters
+for formatting numbers.
+.Pp
+The
+.Fn setlocale
+function recognizes several categories of routines.
+These are the categories and the sets of routines they select:
+.Pp
+.Bl -tag -width LC_MONETARY
+.It Dv LC_ALL
+Set the entire locale generically.
+.It Dv LC_COLLATE
+Set a locale for string collation routines.
+This controls alphabetic ordering in
+.Fn strcoll
+and
+.Fn strxfrm .
+.It Dv LC_CTYPE
+Set a locale for the
+.Xr ctype 3 ,
+.Xr mbrune 3 ,
+.Xr multibyte 3
+and
+.Xr rune 3
+functions.
+This controls recognition of upper and lower case,
+alphabetic or non-alphabetic characters,
+and so on. The real work is done by the
+.Fn setrunelocale
+function.
+.It Dv LC_MONETARY
+Set a locale for formatting monetary values;
+this affects the
+.Fn localeconv
+function.
+.It Dv LC_NUMERIC
+Set a locale for formatting numbers.
+This controls the formatting of decimal points
+in input and output of floating point numbers
+in functions such as
+.Fn printf
+and
+.Fn scanf ,
+as well as values returned by
+.Fn localeconv .
+.It Dv LC_TIME
+Set a locale for formatting dates and times using the
+.Fn strftime
+function.
+.El
+.Pp
+Only three locales are defined by default,
+the empty string
+.Li "\&""\|""
+which denotes the native environment, and the
+.Li "\&""C""
+and
+.LI "\&""POSIX""
+locales, which denote the C language environment.
+A
+.Fa locale
+argument of
+.Dv NULL
+causes
+.Fn setlocale
+to return the current locale.
+By default, C programs start in the
+.Li "\&""C""
+locale.
+The only function in the library that sets the locale is
+.Fn setlocale ;
+the locale is never changed as a side effect of some other routine.
+.Pp
+The
+.Fn localeconv
+function returns a pointer to a structure
+which provides parameters for formatting numbers,
+especially currency values:
+.Bd -literal -offset indent
+struct lconv {
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+ char *int_curr_symbol;
+ char *currency_symbol;
+ char *mon_decimal_point;
+ char *mon_thousands_sep;
+ char *mon_grouping;
+ char *positive_sign;
+ char *negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+};
+.Ed
+.Pp
+The individual fields have the following meanings:
+.Pp
+.Bl -tag -width mon_decimal_point
+.It Fa decimal_point
+The decimal point character, except for currency values.
+.It Fa thousands_sep
+The separator between groups of digits
+before the decimal point, except for currency values.
+.It Fa grouping
+The sizes of the groups of digits, except for currency values.
+This is a pointer to a vector of integers, each of size
+.Va char ,
+representing group size from low order digit groups
+to high order (right to left).
+The list may be terminated with 0 or
+.Dv CHAR_MAX .
+If the list is terminated with 0,
+the last group size before the 0 is repeated to account for all the digits.
+If the list is terminated with
+.Dv CHAR_MAX ,
+no more grouping is performed.
+.It Fa int_curr_symbol
+The standardized international currency symbol.
+.It Fa currency_symbol
+The local currency symbol.
+.It Fa mon_decimal_point
+The decimal point character for currency values.
+.It Fa mon_thousands_sep
+The separator for digit groups in currency values.
+.It Fa mon_grouping
+Like
+.Fa grouping
+but for currency values.
+.It Fa positive_sign
+The character used to denote nonnegative currency values,
+usually the empty string.
+.It Fa negative_sign
+The character used to denote negative currency values,
+usually a minus sign.
+.It Fa int_frac_digits
+The number of digits after the decimal point
+in an international-style currency value.
+.It Fa frac_digits
+The number of digits after the decimal point
+in the local style for currency values.
+.It Fa p_cs_precedes
+1 if the currency symbol precedes the currency value
+for nonnegative values, 0 if it follows.
+.It Fa p_sep_by_space
+1 if a space is inserted between the currency symbol
+and the currency value for nonnegative values, 0 otherwise.
+.It Fa n_cs_precedes
+Like
+.Fa p_cs_precedes
+but for negative values.
+.It Fa n_sep_by_space
+Like
+.Fa p_sep_by_space
+but for negative values.
+.It Fa p_sign_posn
+The location of the
+.Fa positive_sign
+with respect to a nonnegative quantity and the
+.Fa currency_symbol ,
+coded as follows:
+.Bl -tag -width 3n -compact
+.It Li 0
+Parentheses around the entire string.
+.It Li 1
+Before the string.
+.It Li 2
+After the string.
+.It Li 3
+Just before
+.Fa currency_symbol .
+.It Li 4
+Just after
+.Fa currency_symbol .
+.El
+.It Fa n_sign_posn
+Like
+.Fa p_sign_posn
+but for negative currency values.
+.El
+.Pp
+Unless mentioned above,
+an empty string as a value for a field
+indicates a zero length result or
+a value that is not in the current locale.
+A
+.Dv CHAR_MAX
+result similarly denotes an unavailable value.
+.Sh "RETURN VALUES
+The
+.Fn setlocale
+function returns
+.Dv NULL
+and fails to change the locale
+if the given combination of
+.Fa category
+and
+.Fa locale
+makes no sense.
+The
+.Fn localeconv
+function returns a pointer to a static object
+which may be altered by later calls to
+.Fn setlocale
+or
+.Fn localeconv .
+.Sh FILES
+.Bl -tag -width /usr/share/locale/locale/category -compact
+.It Pa $PATH_LOCALE/\fIlocale\fP/\fIcategory\fP
+.It Pa /usr/share/locale/\fIlocale\fP/\fIcategory\fP
+locale file for the locale \fIlocale\fP
+and the category \fIcategory\fP.
+.El
+.Sh "SEE ALSO
+.Xr euc 4 ,
+.Xr mbrune 3 ,
+.Xr multibyte 3 ,
+.Xr rune 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3 ,
+.Xr utf2 4
+.Sh STANDARDS
+The
+.Fn setlocale
+and
+.Fn localeconv
+functions conform to
+.St -ansiC .
+.Sh HISTORY
+The
+.Fn setlocale
+and
+.Fn localeconv
+functions first appeared in 4.4BSD.
+.Sh BUGS
+The current implementation supports only the
+.Li "\&""C""
+and
+.Li "\&""POSIX""
+locales for all but the LC_CTYPE locale.
+.Pp
+In spite of the gnarly currency support in
+.Fn localeconv ,
+the standards don't include any functions
+for generalized currency formatting.
+.Pp
+.Dv LC_COLLATE
+does not make sense for many languages.
+Use of
+.Dv LC_MONETARY
+could lead to misleading results until we have a real time currency
+conversion function.
+.Dv LC_NUMERIC
+and
+.Dv LC_TIME
+are personal choices and should not be wrapped up with the other categories.
diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c
index 247a2782b0c9..414f58ef381a 100644
--- a/lib/libc/locale/setlocale.c
+++ b/lib/libc/locale/setlocale.c
@@ -1,6 +1,9 @@
/*
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,27 +35,200 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)setlocale.c 5.2 (Berkeley) 2/24/91";
+static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
#endif /* LIBC_SCCS and not lint */
+#include <limits.h>
#include <locale.h>
+#include <rune.h>
+#include <stdlib.h>
#include <string.h>
-static char C[] = "C";
+/*
+ * Category names for getenv()
+ */
+static char *categories[_LC_LAST] = {
+ "LC_ALL",
+ "LC_COLLATE",
+ "LC_CTYPE",
+ "LC_MONETARY",
+ "LC_NUMERIC",
+ "LC_TIME",
+};
/*
- * The setlocale function.
- *
- * Sorry, for now we only accept the C locale.
+ * Current locales for each category
*/
+static char current_categories[_LC_LAST][32] = {
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+};
+
+/*
+ * The locales we are going to try and load
+ */
+static char new_categories[_LC_LAST][32];
+
+static char current_locale_string[_LC_LAST * 33];
+static char *PathLocale;
+
+static char *currentlocale __P((void));
+static char *loadlocale __P((int));
+
char *
setlocale(category, locale)
int category;
const char *locale;
{
- if ((unsigned int)category >= _LC_LAST)
+ int found, i, len;
+ char *env, *r;
+
+ if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE")))
+ PathLocale = _PATH_LOCALE;
+
+ if (category < 0 || category >= _LC_LAST)
return (NULL);
- if (locale == NULL)
- return (C);
- return(strcmp(locale, C) ? NULL : C);
+
+ if (!locale)
+ return (category ?
+ current_categories[category] : currentlocale());
+
+ /*
+ * Default to the current locale for everything.
+ */
+ for (i = 1; i < _LC_LAST; ++i)
+ (void)strcpy(new_categories[i], current_categories[i]);
+
+ /*
+ * Now go fill up new_categories from the locale argument
+ */
+ if (!*locale) {
+ env = getenv(categories[category]);
+
+ if (!env)
+ env = getenv(categories[0]);
+
+ if (!env)
+ env = getenv("LANG");
+
+ if (!env)
+ env = "C";
+
+ (void) strncpy(new_categories[category], env, 31);
+ new_categories[category][31] = 0;
+ if (!category) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ if (!(env = getenv(categories[i])))
+ env = new_categories[0];
+ (void)strncpy(new_categories[i], env, 31);
+ new_categories[i][31] = 0;
+ }
+ }
+ } else if (category) {
+ (void)strncpy(new_categories[category], locale, 31);
+ new_categories[category][31] = 0;
+ } else {
+ if ((r = strchr(locale, '/')) == 0) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ (void)strncpy(new_categories[i], locale, 31);
+ new_categories[i][31] = 0;
+ }
+ } else {
+ for (i = 1; r[1] == '/'; ++r);
+ if (!r[1])
+ return (NULL); /* Hmm, just slashes... */
+ do {
+ len = r - locale > 31 ? 31 : r - locale;
+ (void)strncpy(new_categories[i++], locale, len);
+ new_categories[i++][len] = 0;
+ locale = r;
+ while (*locale == '/')
+ ++locale;
+ while (*++r && *r != '/');
+ } while (*locale);
+ while (i < _LC_LAST)
+ (void)strcpy(new_categories[i],
+ new_categories[i-1]);
+ }
+ }
+
+ if (category)
+ return (loadlocale(category));
+
+ found = 0;
+ for (i = 1; i < _LC_LAST; ++i)
+ if (loadlocale(i) != NULL)
+ found = 1;
+ if (found)
+ return (currentlocale());
+ return (NULL);
+}
+
+static char *
+currentlocale()
+{
+ int i;
+
+ (void)strcpy(current_locale_string, current_categories[1]);
+
+ for (i = 2; i < _LC_LAST; ++i)
+ if (strcmp(current_categories[1], current_categories[i])) {
+ (void)snprintf(current_locale_string,
+ sizeof(current_locale_string), "%s/%s/%s/%s/%s",
+ current_categories[1], current_categories[2],
+ current_categories[3], current_categories[4],
+ current_categories[5]);
+ break;
+ }
+ return (current_locale_string);
+}
+
+static char *
+loadlocale(category)
+ int category;
+{
+ char name[PATH_MAX];
+
+ if (strcmp(new_categories[category],
+ current_categories[category]) == 0)
+ return (current_categories[category]);
+
+ if (category == LC_CTYPE) {
+ if (setrunelocale(new_categories[LC_CTYPE]))
+ return (NULL);
+ (void)strcpy(current_categories[LC_CTYPE],
+ new_categories[LC_CTYPE]);
+ return (current_categories[LC_CTYPE]);
+ }
+
+ if (!strcmp(new_categories[category], "C") ||
+ !strcmp(new_categories[category], "POSIX")) {
+
+ /*
+ * Some day this will need to reset the locale to the default
+ * C locale. Since we have no way to change them as of yet,
+ * there is no need to reset them.
+ */
+ (void)strcpy(current_categories[category],
+ new_categories[category]);
+ return (current_categories[category]);
+ }
+
+ /*
+ * Some day we will actually look at this file.
+ */
+ (void)snprintf(name, sizeof(name), "%s/%s/%s",
+ PathLocale, new_categories[category], categories[category]);
+
+ switch (category) {
+ case LC_COLLATE:
+ case LC_MONETARY:
+ case LC_NUMERIC:
+ case LC_TIME:
+ return (NULL);
+ }
}
diff --git a/lib/libc/locale/table.c b/lib/libc/locale/table.c
new file mode 100644
index 000000000000..fb7344eafad5
--- /dev/null
+++ b/lib/libc/locale/table.c
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <rune.h>
+
+extern rune_t _none_sgetrune __P((const char *, size_t, char const **));
+extern int _none_sputrune __P((rune_t, char *, size_t, char **));
+extern int _none_init __P((char *, char **));
+
+_RuneLocale _DefaultRuneLocale = {
+ _RUNE_MAGIC_1,
+ "none",
+ _none_sgetrune,
+ _none_sputrune,
+ 0xFFFD,
+
+ { /*00*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*08*/ _C, _C|_S|_B, _C|_S, _C|_S,
+ _C|_S, _C|_S, _C, _C,
+ /*10*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*18*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*20*/ _S|_B|_R, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*28*/ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*30*/ _D|_R|_G|_X|0, _D|_R|_G|_X|1, _D|_R|_G|_X|2, _D|_R|_G|_X|3,
+ _D|_R|_G|_X|4, _D|_R|_G|_X|5, _D|_R|_G|_X|6, _D|_R|_G|_X|7,
+ /*38*/ _D|_R|_G|_X|8, _D|_R|_G|_X|9, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*40*/ _P|_R|_G, _U|_X|_R|_G|_A|10, _U|_X|_R|_G|_A|11, _U|_X|_R|_G|_A|12,
+ _U|_X|_R|_G|_A|13, _U|_X|_R|_G|_A|14, _U|_X|_R|_G|_A|15, _U|_R|_G|_A,
+ /*48*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ /*50*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ /*58*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*60*/ _P|_R|_G, _L|_X|_R|_G|_A|10, _L|_X|_R|_G|_A|11, _L|_X|_R|_G|_A|12,
+ _L|_X|_R|_G|_A|13, _L|_X|_R|_G|_A|14, _L|_X|_R|_G|_A|15, _L|_R|_G|_A,
+ /*68*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ /*70*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ /*78*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _C,
+ },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ },
+};
+
+_RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale;
+
+int __mb_cur_max = 1;
diff --git a/lib/libc/locale/utf2.4 b/lib/libc/locale/utf2.4
new file mode 100644
index 000000000000..c46f4f986c41
--- /dev/null
+++ b/lib/libc/locale/utf2.4
@@ -0,0 +1,87 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" 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 the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+.\"
+.\" @(#)utf2.4 8.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.Dt UTF2 4
+.Os
+.Sh NAME
+.Nm UTF2
+.Nd "Universal character set Transformation Format encoding of runes
+.Sh SYNOPSIS
+\fBENCODING "UTF2"\fP
+.Sh DESCRIPTION
+The
+.Nm UTF2
+encoding is based on a proposed X-Open multibyte
+\s-1FSS-UCS-TF\s+1 (File System Safe Universal Character Set Transformation Format) encoding as used in
+.Nm Plan 9 from Bell Labs.
+Although it is capable of representing more than 16 bits,
+the current implementation is limited to 16 bits as defined by the
+Unicode Standard.
+UTF2 is also called UTF8 in some circles.
+.Pp
+.Nm UTF2
+representation is backwards compatible with ASCII, so 0x00-0x7f refer to the
+ASCII character set. The multibyte encoding of runes between 0x0080 and 0xffff
+consist entirely of bytes whose high order bit is set. The actual
+encoding is represented by the following table:
+.Bd -literal
+[0x0000 - 0x007f] [00000000.0bbbbbbb] -> 0bbbbbbb
+[0x0080 - 0x03ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb
+[0x0400 - 0xffff] [bbbbbbbb.bbbbbbbb] -> 1110bbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.sp
+If more than a single representation of a value exists (for example,
+0x00; 0xC0 0x80; 0xE0 0x80 0x80) the shortest representation is always
+used (but the longer ones will be correctly decoded).
+.Pp
+The final three encodings provided by X-Open:
+.Bd -literal
+[00000000.000bbbbb.bbbbbbbb.bbbbbbbb] ->
+ 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+
+[000000bb.bbbbbbbb.bbbbbbbb.bbbbbbbb] ->
+ 111110bb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+
+[0bbbbbbb.bbbbbbbb.bbbbbbbb.bbbbbbbb] ->
+ 1111110b, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.sp
+which provides for the entire proposed ISO-10646 31 bit standard are currently
+not implemented.
+.Sh "SEE ALSO"
+.Xr mklocale 1 ,
+.Xr setlocale 3
diff --git a/lib/libc/locale/utf2.c b/lib/libc/locale/utf2.c
new file mode 100644
index 000000000000..846fad90ed6f
--- /dev/null
+++ b/lib/libc/locale/utf2.c
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)utf2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+rune_t _UTF2_sgetrune __P((const char *, size_t, char const **));
+int _UTF2_sputrune __P((rune_t, char *, size_t, char **));
+
+static _utf_count[16] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 2, 2, 3, 0,
+};
+
+int
+_UTF2_init(rl)
+ _RuneLocale *rl;
+{
+ rl->sgetrune = _UTF2_sgetrune;
+ rl->sputrune = _UTF2_sputrune;
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 3;
+ return (0);
+}
+
+rune_t
+_UTF2_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ int c;
+
+ if (n < 1 || (c = _utf_count[(*string >> 4) & 0xf]) > n) {
+ if (result)
+ *result = string;
+ return (_INVALID_RUNE);
+ }
+ switch (c) {
+ case 1:
+ if (result)
+ *result = string + 1;
+ return (*string & 0xff);
+ case 2:
+ if ((string[1] & 0xC0) != 0x80)
+ goto encoding_error;
+ if (result)
+ *result = string + 2;
+ return (((string[0] & 0x1F) << 6) | (string[1] & 0x3F));
+ case 3:
+ if ((string[1] & 0xC0) != 0x80 || (string[2] & 0xC0) != 0x80)
+ goto encoding_error;
+ if (result)
+ *result = string + 3;
+ return (((string[0] & 0x1F) << 12) | ((string[1] & 0x3F) << 6)
+ | (string[2] & 0x3F));
+ default:
+encoding_error: if (result)
+ *result = string + 1;
+ return (_INVALID_RUNE);
+ }
+}
+
+int
+_UTF2_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ if (c & 0xF800) {
+ if (n >= 3) {
+ if (string) {
+ string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ string[1] = 0x80 | ((c >> 6) & 0x3F);
+ string[2] = 0x80 | ((c) & 0x3F);
+ }
+ if (result)
+ *result = string + 3;
+ } else
+ if (result)
+ *result = NULL;
+
+ return (3);
+ } else
+ if (c & 0x0780) {
+ if (n >= 2) {
+ if (string) {
+ string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ string[1] = 0x80 | ((c) & 0x3F);
+ }
+ if (result)
+ *result = string + 2;
+ } else
+ if (result)
+ *result = NULL;
+ return (2);
+ } else {
+ if (n >= 1) {
+ if (string)
+ string[0] = c;
+ if (result)
+ *result = string + 1;
+ } else
+ if (result)
+ *result = NULL;
+ return (1);
+ }
+}
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
index 2b1597a20796..b4c154672d58 100644
--- a/lib/libc/net/gethostnamadr.c
+++ b/lib/libc/net/gethostnamadr.c
@@ -120,6 +120,7 @@ init_services()
service_order[cc++] = SERVICE_NIS;
}
service_order[cc] = SERVICE_NONE;
+ fclose(fd);
}
service_done = 1;
}
diff --git a/lib/libc/net/ns_addr.c b/lib/libc/net/ns_addr.c
index e31e6d13570f..684dd8e79165 100644
--- a/lib/libc/net/ns_addr.c
+++ b/lib/libc/net/ns_addr.c
@@ -55,8 +55,8 @@ ns_addr(name)
char *hostname, *socketname, *cp;
char buf[50];
- (void)strncpy(buf, name, sizeof(buf - 1));
- buf[sizeof(buf - 1)] = '\0';
+ (void)strncpy(buf, name, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
/*
* First, figure out what he intends as a field separtor.
diff --git a/lib/libc/net/rcmd.c b/lib/libc/net/rcmd.c
index d0cd18000ba9..5d1a575fe110 100644
--- a/lib/libc/net/rcmd.c
+++ b/lib/libc/net/rcmd.c
@@ -38,6 +38,7 @@ static char sccsid[] = "@(#)rcmd.c 5.24 (Berkeley) 2/24/91";
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
@@ -138,7 +139,7 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
FD_SET(s, &reads);
FD_SET(s2, &reads);
errno = 0;
- if (select(32, &reads, 0, 0, 0) < 1 ||
+ if (select(FD_SETSIZE, &reads, 0, 0, 0) < 1 ||
!FD_ISSET(s2, &reads)) {
if (errno != 0)
perror("select: setting up stderr");
@@ -230,6 +231,12 @@ ruserok(rhost, superuser, ruser, luser)
int first = 1;
register char *sp, *p;
int baselen = -1;
+ uid_t suid;
+ gid_t sgid;
+ int int_sgid; /* this is a kludge and should be removed
+ when we transition to FreeBSD 2.0. If you
+ find this code in a 2.0 source tree, please
+ contact the core team. */
sp = (char *)rhost;
p = fhost;
@@ -248,6 +255,12 @@ again:
if (hostf) {
if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
(void) fclose(hostf);
+ if (first == 0) {
+ (void)seteuid(suid);
+ (void)setegid(sgid);
+ int_sgid = sgid;
+ (void)setgroups(1, &int_sgid);
+ }
return(0);
}
(void) fclose(hostf);
@@ -258,12 +271,17 @@ again:
char pbuf[MAXPATHLEN];
first = 0;
+ suid = geteuid();
+ sgid = getegid();
if ((pwd = getpwnam(luser)) == NULL)
return(-1);
+ (void)setegid(pwd->pw_gid);
+ (void)initgroups(luser, pwd->pw_gid);
+ (void)seteuid(pwd->pw_uid);
(void)strcpy(pbuf, pwd->pw_dir);
(void)strcat(pbuf, "/.rhosts");
if ((hostf = fopen(pbuf, "r")) == NULL)
- return(-1);
+ goto bad;
/*
* if owned by someone other than user or root or if
* writeable by anyone but the owner, quit
@@ -272,10 +290,16 @@ again:
sbuf.st_uid && sbuf.st_uid != pwd->pw_uid ||
sbuf.st_mode&022) {
fclose(hostf);
- return(-1);
+ goto bad;
}
goto again;
}
+bad:
+ if (first == 0) {
+ (void)seteuid(suid);
+ (void)setegid(sgid);
+ (void)setgroups(1, (int *)&sgid);
+ }
return (-1);
}
diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc
index ad87006fbac7..3fd05f51ffc3 100644
--- a/lib/libc/stdio/Makefile.inc
+++ b/lib/libc/stdio/Makefile.inc
@@ -3,8 +3,9 @@
# stdio sources
.PATH: ${.CURDIR}/stdio
-SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
- fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
+SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c \
+ fgetc.c fgetline.c fgetln.c fgetpos.c fgets.c \
+ fileno.c findfp.c flags.c fopen.c \
fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
getc.c getchar.c gets.c getw.c makebuf.c perror.c printf.c putc.c \
@@ -14,7 +15,7 @@ SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
wbuf.c wsetup.c
-MAN3+= stdio/fclose.3 stdio/ferror.3 stdio/fflush.3 stdio/fgetline.3 \
+MAN3+= stdio/fclose.3 stdio/ferror.3 stdio/fflush.3 stdio/fgetln.3 \
stdio/fgets.3 stdio/fopen.3 stdio/fputs.3 stdio/fread.3 \
stdio/fseek.3 stdio/funopen.3 stdio/getc.3 stdio/mktemp.3 \
stdio/printf.3 stdio/putc.3 stdio/remove.3 stdio/scanf.3 \
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
index 27d873f2073f..974cd444853d 100644
--- a/lib/libc/stdio/fclose.c
+++ b/lib/libc/stdio/fclose.c
@@ -48,7 +48,7 @@ fclose(fp)
{
register int r;
- if (fp->_flags == 0) { /* not open! */
+ if (!fp || (fp->_flags == 0)) { /* not open! */
errno = EBADF;
return (EOF);
}
diff --git a/lib/libc/stdio/fgetline.c b/lib/libc/stdio/fgetline.c
index bcd80aca4e86..70fe9d65fe5b 100644
--- a/lib/libc/stdio/fgetline.c
+++ b/lib/libc/stdio/fgetline.c
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)fgetline.c 5.2 (Berkeley) 5/4/91";
* The `new size' does not account for a terminating '\0',
* so we add 1 here.
*/
+static int
__slbexpand(fp, newsize)
FILE *fp;
size_t newsize;
diff --git a/lib/libc/stdio/fgetline.3 b/lib/libc/stdio/fgetln.3
index 745e745c66f6..a453cff29c13 100644
--- a/lib/libc/stdio/fgetline.3
+++ b/lib/libc/stdio/fgetln.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1990, 1991 The Regents of the University of California.
-.\" All rights reserved.
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -29,32 +29,37 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)fgetline.3 5.4 (Berkeley) 4/19/91
+.\" from: @(#)fgetline.3 8.1 (Berkeley) 6/9/93
+.\" $Id: fgetln.3,v 1.1 1994/04/17 09:16:36 alm Exp $
.\"
-.Dd April 19, 1991
-.Dt FGETLINE 3
+.Dd June 9, 1993
+.Dt FGETLN 3
.Os
.Sh NAME
-.Nm fgetline
+.Nm fgetln
.Nd get a line from a stream
.Sh SYNOPSIS
.Fd #include <stdio.h>
.Ft char *
-.Fn fgetline "FILE *stream" "size_t *len"
+.Fn fgetln "FILE *stream" "size_t *len"
.Sh DESCRIPTION
The
-.Fn fgetline
+.Fn fgetln
function
returns a pointer to the next line from the stream referenced by
.Fa stream .
-The newline character at the end of the line is replaced by a
-.Dv NUL .
-.Pp
-If
+This line is
+.Em not
+a C string as it does not end with a terminating
+.Dv NUL
+character.
+The length of the line, including the final newline,
+is stored in the memory location to which
.Fa len
-is non-NULL, the length of the line, not counting the terminating
-.Dv NUL ,
-is stored in the memory location it references.
+points.
+(Note, however, that if the line is the last
+in a file that does not end in a newline,
+the returned text will not contain a newline.)
.Sh RETURN VALUES
Upon successful completion a pointer is returned;
this pointer becomes invalid after the next
@@ -67,7 +72,7 @@ Otherwise,
.Dv NULL
is returned.
The
-.Fn fgetline
+.Fn fgetln
function
does not distinguish between end-of-file and error; the routines
.Xr feof 3
@@ -75,7 +80,7 @@ and
.Xr ferror 3
must be used
to determine which occurred.
-If an error occurrs, the global variable
+If an error occurs, the global variable
.Va errno
is set to indicate the error.
The end-of-file condition is remembered, even on a terminal, and all
@@ -86,8 +91,7 @@ cleared with
.Xr clearerr 3 .
.Pp
The text to which the returned pointer points may be modified,
-provided that no changes are made beyond the terminating
-.Dv NUL .
+provided that no changes are made beyond the returned size.
These changes are lost as soon as the pointer becomes invalid.
.Sh ERRORS
.Bl -tag -width [EBADF]
@@ -98,7 +102,7 @@ is not a stream open for reading.
.El
.Pp
The
-.Fn fgetline
+.Fn fgetln
function
may also fail and set
.Va errno
@@ -116,9 +120,5 @@ or
.Xr putc 3
.Sh HISTORY
The
-.Fn fgetline
-function is
-.Ud .
-.Sh BUGS
-It is not possible to tell whether the final line of an input file
-was terminated with a newline.
+.Fn fgetln
+function first appeared in 4.4BSD.
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
new file mode 100644
index 000000000000..992b4b57e088
--- /dev/null
+++ b/lib/libc/stdio/fgetln.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)fgetline.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$Id: fgetln.c,v 1.1 1994/04/17 09:16:39 alm Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+
+/*
+ * Expand the line buffer. Return -1 on error.
+#ifdef notdef
+ * The `new size' does not account for a terminating '\0',
+ * so we add 1 here.
+#endif
+ */
+int
+__slbexpand(fp, newsize)
+ FILE *fp;
+ size_t newsize;
+{
+ void *p;
+
+#ifdef notdef
+ ++newsize;
+#endif
+ if (fp->_lb._size >= newsize)
+ return (0);
+ if ((p = realloc(fp->_lb._base, newsize)) == NULL)
+ return (-1);
+ fp->_lb._base = p;
+ fp->_lb._size = newsize;
+ return (0);
+}
+
+/*
+ * Get an input line. The returned pointer often (but not always)
+ * points into a stdio buffer. Fgetline does not alter the text of
+ * the returned line (which is thus not a C string because it will
+ * not necessarily end with '\0'), but does allow callers to modify
+ * it if they wish. Thus, we set __SMOD in case the caller does.
+ */
+char *
+fgetln(fp, lenp)
+ register FILE *fp;
+ size_t *lenp;
+{
+ register unsigned char *p;
+ register size_t len;
+ size_t off;
+
+ /* make sure there is input */
+ if (fp->_r <= 0 && __srefill(fp)) {
+ *lenp = 0;
+ return (NULL);
+ }
+
+ /* look for a newline in the input */
+ if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
+ register char *ret;
+
+ /*
+ * Found one. Flag buffer as modified to keep fseek from
+ * `optimising' a backward seek, in case the user stomps on
+ * the text.
+ */
+ p++; /* advance over it */
+ ret = (char *)fp->_p;
+ *lenp = len = p - fp->_p;
+ fp->_flags |= __SMOD;
+ fp->_r -= len;
+ fp->_p = p;
+ return (ret);
+ }
+
+ /*
+ * We have to copy the current buffered data to the line buffer.
+ * As a bonus, though, we can leave off the __SMOD.
+ *
+ * OPTIMISTIC is length that we (optimistically) expect will
+ * accomodate the `rest' of the string, on each trip through the
+ * loop below.
+ */
+#define OPTIMISTIC 80
+
+ for (len = fp->_r, off = 0;; len += fp->_r) {
+ register size_t diff;
+
+ /*
+ * Make sure there is room for more bytes. Copy data from
+ * file buffer to line buffer, refill file and look for
+ * newline. The loop stops only when we find a newline.
+ */
+ if (__slbexpand(fp, len + OPTIMISTIC))
+ goto error;
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
+ len - off);
+ off = len;
+ if (__srefill(fp))
+ break; /* EOF or error: return partial line */
+ if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
+ continue;
+
+ /* got it: finish up the line (like code above) */
+ p++;
+ diff = p - fp->_p;
+ len += diff;
+ if (__slbexpand(fp, len))
+ goto error;
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
+ diff);
+ fp->_r -= diff;
+ fp->_p = p;
+ break;
+ }
+ *lenp = len;
+#ifdef notdef
+ fp->_lb._base[len] = 0;
+#endif
+ return ((char *)fp->_lb._base);
+
+error:
+ *lenp = 0; /* ??? */
+ return (NULL); /* ??? */
+}
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
index a027109e5659..a8fb89449ed0 100644
--- a/lib/libc/stdio/fseek.c
+++ b/lib/libc/stdio/fseek.c
@@ -197,7 +197,7 @@ fseek(fp, offset, whence)
* If the target offset is within the current buffer,
* simply adjust the pointers, clear EOF, undo ungetc(),
* and return. (If the buffer was modified, we have to
- * skip this; see fgetline.c.)
+ * skip this; see fgetln.c.)
*/
if ((fp->_flags & __SMOD) == 0 &&
target >= curoff && target < curoff + n) {
diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c
index 4f1622369dbc..12fc115bc64f 100644
--- a/lib/libc/stdio/gets.c
+++ b/lib/libc/stdio/gets.c
@@ -35,11 +35,16 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)gets.c 5.3 (Berkeley) 1/20/91";
+static char sccsid[] = "From: @(#)gets.c 5.3 (Berkeley) 1/20/91";
+static char rcsid[] =
+ "$Id: gets.c,v 1.3 1994/04/23 20:35:27 wollman Exp $";
#endif /* LIBC_SCCS and not lint */
#include <unistd.h>
#include <stdio.h>
+#include <string.h>
+
+#define MESSAGE ": warning: this program uses gets(), which is unsafe.\r\n"
char *
gets(buf)
@@ -48,11 +53,11 @@ gets(buf)
register int c;
register char *s;
static int warned;
- static char w[] =
- "warning: this program uses gets(), which is unsafe.\r\n";
if (!warned) {
- (void) write(STDERR_FILENO, w, sizeof(w) - 1);
+ extern char *__progname;
+ write(2, __progname, strlen(__progname));
+ write(2, MESSAGE, sizeof(MESSAGE) - 1);
warned = 1;
}
for (s = buf; (c = getchar()) != '\n';)
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
index 21966d704dbd..87ed4e60d23e 100644
--- a/lib/libc/stdio/local.h
+++ b/lib/libc/stdio/local.h
@@ -78,7 +78,7 @@ extern int __sdidinit;
}
/*
- * test for an fgetline() buffer.
+ * test for an fgetln() buffer.
*/
#define HASLB(fp) ((fp)->_lb._base != NULL)
#define FREELB(fp) { \
diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
index 130246ea1b0a..0d7c52873881 100644
--- a/lib/libc/stdio/printf.3
+++ b/lib/libc/stdio/printf.3
@@ -402,7 +402,7 @@ are used for
conversions; the letters
.Cm ABCDEF
are used for
-.m X
+.Cm X
conversions.
The precision, if any, gives the minimum number of digits that must
appear; if the converted value requires fewer digits, it is padded on
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 0bd1a90ab56a..c5736ba7172f 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -4,7 +4,7 @@
.PATH: ${.CURDIR}/${MACHINE}/stdlib ${.CURDIR}/stdlib
SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c exit.c \
- getenv.c getopt.c heapsort.c malloc.c multibyte.c \
+ getenv.c getopt.c heapsort.c malloc.c \
putenv.c qsort.c radixsort.c rand.c random.c setenv.c strtod.c \
strtol.c strtoul.c system.c \
_rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c
index f96af3005605..3879281d2581 100644
--- a/lib/libc/stdlib/rand.c
+++ b/lib/libc/stdlib/rand.c
@@ -43,7 +43,7 @@ static u_long next = 1;
int
rand()
{
- return ((next = next * 1103515245 + 12345) % (RAND_MAX + 1));
+ return ((next = next * 1103515245 + 12345) % ((u_long)RAND_MAX + 1));
}
void
diff --git a/lib/libc/string/index.3 b/lib/libc/string/index.3
index 12ca7112a402..f387409fc51f 100644
--- a/lib/libc/string/index.3
+++ b/lib/libc/string/index.3
@@ -54,7 +54,7 @@ locates the first character matching
in the null-terminated string
.Fa s .
.Sh RETURN VALUES
-The character
+The location of the character
.Fa c
is returned if it is found; otherwise
.Dv NULL
diff --git a/lib/libc/string/strftime.c b/lib/libc/string/strftime.c
index 16879d256821..99c68f9b31e2 100644
--- a/lib/libc/string/strftime.c
+++ b/lib/libc/string/strftime.c
@@ -196,6 +196,7 @@ _fmt(format, t)
case 'R':
if (!_fmt("%H:%M", t))
return(0);
+ continue;
case 'r':
if (!_fmt(t_fmt_ampm, t))
return(0);
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 3deb3bbcc702..d0689839bf9d 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -1,4 +1,5 @@
-# @(#)Makefile.inc 5.11 (Berkeley) 6/23/91
+# From: @(#)Makefile.inc 5.11 (Berkeley) 6/23/91
+# $Id: Makefile.inc,v 1.16 1994/03/16 19:01:06 wollman Exp $
# sys sources
.PATH: ${.CURDIR}/${MACHINE}/sys ${.CURDIR}/sys
@@ -19,7 +20,8 @@ ASM= accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \
getpriority.o getrlimit.o getrusage.o getsockname.o getsockopt.o \
gettimeofday.o getuid.o ioctl.o kill.o ktrace.o link.o listen.o \
lseek.o lstat.o madvise.o mincore.o mkdir.o mkfifo.o mknod.o \
- mmap.o mount.o mprotect.o msgsys.o msync.o munmap.o nfssvc.o open.o \
+ mmap.o mount.o mprotect.o msgsys.o msync.o munmap.o nfssvc.o \
+ ntp_adjtime.o ntp_gettime.o open.o \
profil.o quotactl.o read.o readlink.o readv.o recvfrom.o recvmsg.o \
rename.o revoke.o rmdir.o select.o semsys.o sendmsg.o sendto.o \
setdomainname.o setegid.o seteuid.o setgid.o setgroups.o sethostid.o \
@@ -96,7 +98,7 @@ MAN2+= sys/accept.2 sys/access.2 sys/acct.2 sys/adjtime.2 sys/async_daemon.2 \
sys/msync.2 sys/munmap.2 sys/nfssvc.2 sys/open.2 sys/pipe.2 \
sys/quotactl.2 sys/read.2 sys/readlink.2 sys/reboot.2 sys/recv.2 \
sys/rename.2 sys/rmdir.2 sys/select.2 sys/send.2 sys/setgroups.2 \
- sys/setpgid.2 sys/setregid.2 sys/setreuid.2 sys/setsid.2 \
+ sys/setpgid.2 sys/setregid.2 sys/setreuid.2 sys/setsid.2 sys/setuid.2 \
sys/shutdown.2 sys/sigaction.2 sys/sigprocmask.2 sys/sigreturn.2 \
sys/sigstack.2 sys/sigsuspend.2 sys/socket.2 sys/socketpair.2 \
sys/stat.2 sys/statfs.2 sys/swapon.2 sys/symlink.2 sys/sync.2 \
@@ -127,6 +129,7 @@ MLINKS+=mount.2 unmount.2
MLINKS+=read.2 readv.2
MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
MLINKS+=send.2 sendmsg.2 send.2 sendto.2
+MLINKS+=setuid.2 setegid.2 setuid.2 seteuid.2 setuid.2 setgid.2
MLINKS+=setpgid.2 setpgrp.2
MLINKS+=stat.2 fstat.2 stat.2 lstat.2
MLINKS+=statfs.2 fstatfs.2
diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
index 726de1f88448..48405320181d 100644
--- a/lib/libc/sys/execve.2
+++ b/lib/libc/sys/execve.2
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)execve.2 6.9 (Berkeley) 3/10/91
-.\" $Id: execve.2,v 1.2.2.1 1994/05/01 16:06:05 jkh Exp $
+.\" $Id: execve.2,v 1.4 1994/03/16 19:10:39 wollman Exp $
.\"
.Dd March 16, 1994
.Dt EXECVE 2
diff --git a/lib/libc/sys/setregid.2 b/lib/libc/sys/setregid.2
index 86b0aa7949be..764f89403e3a 100644
--- a/lib/libc/sys/setregid.2
+++ b/lib/libc/sys/setregid.2
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)setregid.2 6.4 (Berkeley) 3/10/91
-.\" $Id: setregid.2,v 1.1.1.1.2.1 1994/05/01 16:06:13 jkh Exp $
+.\" $Id: setregid.2,v 1.2 1994/03/16 19:01:08 wollman Exp $
.\"
.Dd March 16, 1994
.Dt SETREGID 2
diff --git a/lib/libc/sys/setreuid.2 b/lib/libc/sys/setreuid.2
index de34b029ab57..62f5dcdae68d 100644
--- a/lib/libc/sys/setreuid.2
+++ b/lib/libc/sys/setreuid.2
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)setreuid.2 6.4 (Berkeley) 3/10/91
-.\" $Id: setreuid.2,v 1.1.1.1.2.1 1994/05/01 16:06:14 jkh Exp $
+.\" $Id: setreuid.2,v 1.2 1994/03/16 19:01:09 wollman Exp $
.\"
.Dd March 16, 1994
.Dt SETREUID 2
diff --git a/lib/libc/gen/setuid.3 b/lib/libc/sys/setuid.2
index 4e0e4c3c9ea5..eb596cc4918f 100644
--- a/lib/libc/gen/setuid.3
+++ b/lib/libc/sys/setuid.2
@@ -29,18 +29,19 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)setuid.3 6.4 (Berkeley) 4/19/91
+.\" From: @(#)setuid.3 6.4 (Berkeley) 4/19/91
+.\" $Id: setuid.2,v 1.2 1994/04/21 21:30:20 wollman Exp $
.\"
-.Dd April 19, 1991
-.Dt SETUID 3
-.Os BSD 4.2
+.Dd March 16, 1994
+.Dt SETUID 2
+.Os
.Sh NAME
.Nm setuid ,
.Nm seteuid ,
-.Nm setruid ,
+.\" .Nm setruid ,
.Nm setgid ,
.Nm setegid ,
-.Nm setrgid
+.\" .Nm setrgid
.Nd set user and group ID
.Sh SYNOPSIS
.Fd #include <sys/types.h>
@@ -48,21 +49,21 @@
.Fn setuid "uid_t uid"
.Ft int
.Fn seteuid "uid_t euid"
-.Ft int
-.Fn setruid "uid_t ruid"
+.\" .Ft int
+.\" .Fn setruid "uid_t ruid"
.Ft int
.Fn setgid "gid_t gid"
.Ft int
.Fn setegid "gid_t egid"
-.Ft int
-.Fn setrgid "gid_t rgid"
+.\" .Ft int
+.\" .Fn setrgid "gid_t rgid"
.Sh DESCRIPTION
The
.Fn setuid
function
.Pq Fn setgid
-sets both the real and effective
-user ID (group ID) of the current process
+sets the real, effective, and saved
+user IDs (group IDs) of the current process
as specified.
.Pp
The
@@ -71,25 +72,46 @@ function
.Pq Fn setegid
sets the effective user ID (group ID) of the
current process.
+.\".Pp
+.\" The
+.\" .Fn setruid
+.\" function
+.\" .Pq Fn setrgid
+.\" sets the real user ID (group ID) of the
+.\" current process.
.Pp
-The
-.Fn setruid
-function
-.Pq Fn setrgid
-sets the real user ID (group ID) of the
-current process.
+When any of these calls succeed, the
+.Dv SUGID
+process flag is turned on, and remains on until the process calls
+.Xr execve 2 ;
+this flag can be inspected with
+.Xr ps 1 .
.Sh RETURN VALUES
Upon success, these functions return 0;
otherwise \-1 is returned.
.Pp
-If the user is not the super user, or the uid
-specified is not the real or effective ID, these
+If the user is not the super user, and the ID specified is not the
+current real ID, the
+.Nm setuid
+and
+.Nm setgid
+functions return \-1.
+.Pp
+If the user is not the super user, and the ID specfied is not the
+current real ID, the
+.\" nor the saved ID, the
+.\" should this really be true that setuid(geteuid()) is not allowed?
+.Nm seteuid
+and
+.Nm setegid
functions return \-1.
.Sh SEE ALSO
.Xr setreuid 2 ,
.Xr setregid 2 ,
.Xr getuid 2 ,
-.Xr getgid 2
+.Xr getgid 2 ,
+.Xr execve 2 ,
+.Xr ps 1
.Sh HISTORY
A
.Fn setuid
diff --git a/lib/libc/sys/sigsuspend.2 b/lib/libc/sys/sigsuspend.2
index 8e0c73001c10..2b09e707f5e5 100644
--- a/lib/libc/sys/sigsuspend.2
+++ b/lib/libc/sys/sigsuspend.2
@@ -36,7 +36,7 @@
.Os
.Sh NAME
.Nm sigsuspend
-.Nd automatically release blocked signals and wait for interrupt
+.Nd atomically release blocked signals and wait for interrupt
.Sh SYNOPSIS
.Fd #include <sys/signal.h>
.Ft int
@@ -74,7 +74,7 @@ set to
.Xr sigsetops 3
.Sh STANDARDS
The
-.Nm sigsupend
+.Nm sigsuspend
function call
conforms to
.St -p1003.1-88 .