svn commit: r226973 - in projects/varsym: . bin/ln lib/libc/sys
lib/libutil sys/amd64/conf sys/compat/freebsd32 sys/conf
sys/kern sys/sys tools/regression/usr.bin/varsym usr.bin/varsym
Brooks Davis
brooks at FreeBSD.org
Mon Oct 31 23:27:25 UTC 2011
Author: brooks
Date: Mon Oct 31 23:27:24 2011
New Revision: 226973
URL: http://svn.freebsd.org/changeset/base/226973
Log:
Bring in an updated varsym patch from my P4 tree.
Added:
projects/varsym/TODO
projects/varsym/lib/libc/sys/varsym.2
projects/varsym/sys/kern/kern_varsym.c
projects/varsym/sys/sys/varsym.h
projects/varsym/tools/regression/usr.bin/varsym/
projects/varsym/tools/regression/usr.bin/varsym/Makefile
projects/varsym/tools/regression/usr.bin/varsym/regress.all_unset.out
projects/varsym/tools/regression/usr.bin/varsym/regress.all_unset_default.out
projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_get.out
projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_list.out
projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_set.out
projects/varsym/tools/regression/usr.bin/varsym/regress.list_basic.out
projects/varsym/tools/regression/usr.bin/varsym/regress.list_clear_proc.out
projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set.out
projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set_denied.out
projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set_toomany.out
projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_override.out
projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_proc.out
projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_sys.out
projects/varsym/tools/regression/usr.bin/varsym/regress.proc_basic.out
projects/varsym/tools/regression/usr.bin/varsym/regress.sh
projects/varsym/tools/regression/usr.bin/varsym/regress.sys_basic.out
projects/varsym/tools/regression/usr.bin/varsym/regress.sys_cleared.out
projects/varsym/tools/regression/usr.bin/varsym/regress.sys_deleted.out
projects/varsym/tools/regression/usr.bin/varsym/regress.sys_override.out
projects/varsym/tools/regression/usr.bin/varsym/regress.t
projects/varsym/usr.bin/varsym/
projects/varsym/usr.bin/varsym/Makefile
projects/varsym/usr.bin/varsym/varsym.1
projects/varsym/usr.bin/varsym/varsym.c
Modified:
projects/varsym/bin/ln/ln.1
projects/varsym/lib/libc/sys/Makefile.inc
projects/varsym/lib/libc/sys/Symbol.map
projects/varsym/lib/libutil/login.conf.5
projects/varsym/lib/libutil/login_cap.h
projects/varsym/lib/libutil/login_class.3
projects/varsym/lib/libutil/login_class.c
projects/varsym/sys/amd64/conf/GENERIC
projects/varsym/sys/compat/freebsd32/freebsd32_misc.c
projects/varsym/sys/compat/freebsd32/freebsd32_proto.h
projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h
projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c
projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c
projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c
projects/varsym/sys/compat/freebsd32/syscalls.master
projects/varsym/sys/conf/files
projects/varsym/sys/conf/options
projects/varsym/sys/kern/init_sysent.c
projects/varsym/sys/kern/kern_exec.c
projects/varsym/sys/kern/kern_fork.c
projects/varsym/sys/kern/syscalls.c
projects/varsym/sys/kern/syscalls.master
projects/varsym/sys/kern/systrace_args.c
projects/varsym/sys/kern/vfs_lookup.c
projects/varsym/sys/sys/priv.h
projects/varsym/sys/sys/proc.h
projects/varsym/sys/sys/syscall.h
projects/varsym/sys/sys/syscall.mk
projects/varsym/sys/sys/sysproto.h
Added: projects/varsym/TODO
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/varsym/TODO Mon Oct 31 23:27:24 2011 (r226973)
@@ -0,0 +1,5 @@
+pre-commit:
+- get review, tweak as necessicary
+
+post-commit:
+- add jail or vimage support
Modified: projects/varsym/bin/ln/ln.1
==============================================================================
--- projects/varsym/bin/ln/ln.1 Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/bin/ln/ln.1 Mon Oct 31 23:27:24 2011 (r226973)
@@ -212,6 +212,47 @@ No options may be supplied in this simpl
which performs a
.Xr link 2
operation using the two passed arguments.
+.Sh VARIANT SYMLINKS
+.Dx
+supports a special kind of dynamic
+symbolic link called a
+.Em variant symlink .
+The
+.Ar source_file
+of a variant symlink may contain one or more
+variable names. Each of these variable
+names is enclosed in braces and preceded by a
+dollar sign in the style of variable references in
+.Xr sh 1
+and
+.Xr csh 1 .
+.Pp
+Whenever a variant symlink is followed, each
+variable found in
+.Ar source_file
+is replaced by its associated value.
+In this manner, a variant symlink may resolve to different
+paths based on context. The facility
+supports per-process, per-user, and system-wide varsyms.
+.Pp
+Varsym variables can be set with the
+.Xr varsym 1
+utility. Regular
+.Xr environ 7
+environment variables are
+not used to resolve variant symlinks.
+.Ss EXAMPLE
+.Bd -literal -offset indent
+sysctl -w vfs.varsym.enable=1
+
+ln -s 'a%{fubar}b' test
+
+echo 'Hello' > axxb
+echo 'Goodbye' > ayyb
+
+varsym fubar=xx cat test
+varsym fubar=yy cat test
+.Ed
.Sh COMPATIBILITY
The
.Fl h ,
@@ -236,7 +277,8 @@ extension and should not be used in port
.Xr readlink 2 ,
.Xr stat 2 ,
.Xr symlink 2 ,
-.Xr symlink 7
+.Xr symlink 7 ,
+.Xr varsym 1
.Sh STANDARDS
The
.Nm
@@ -251,4 +293,4 @@ command conforms to
An
.Nm
command appeared in
-.At v1 .
+.At v1 . Variant Symlinks appeared in DragonFly BSD .
Modified: projects/varsym/lib/libc/sys/Makefile.inc
==============================================================================
--- projects/varsym/lib/libc/sys/Makefile.inc Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/lib/libc/sys/Makefile.inc Mon Oct 31 23:27:24 2011 (r226973)
@@ -114,7 +114,7 @@ MAN+= sctp_generic_recvmsg.2 sctp_generi
swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \
timer_create.2 timer_delete.2 timer_settime.2 \
truncate.2 umask.2 undelete.2 \
- unlink.2 utimes.2 utrace.2 uuidgen.2 vfork.2 wait.2 write.2
+ unlink.2 utimes.2 utrace.2 uuidgen.2 varsym.2 vfork.2 wait.2 write.2
MLINKS+=access.2 eaccess.2 access.2 faccessat.2
MLINKS+=brk.2 sbrk.2
@@ -210,4 +210,5 @@ MLINKS+=truncate.2 ftruncate.2
MLINKS+=unlink.2 unlinkat.2
MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
-MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2
+MLINKS+=write.2 pwrite.2 write.2 writev.2 write.2 pwritev.2
+MLINKS+=varsym.2 varsym_set.2 varsym.2 varsym_get.2 varsym.2 varsym_list.2
Modified: projects/varsym/lib/libc/sys/Symbol.map
==============================================================================
--- projects/varsym/lib/libc/sys/Symbol.map Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/lib/libc/sys/Symbol.map Mon Oct 31 23:27:24 2011 (r226973)
@@ -326,6 +326,9 @@ FBSD_1.0 {
pread;
pwrite;
truncate;
+ varsym_set;
+ varsym_get;
+ varsym_list;
};
FBSD_1.1 {
Added: projects/varsym/lib/libc/sys/varsym.2
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/varsym/lib/libc/sys/varsym.2 Mon Oct 31 23:27:24 2011 (r226973)
@@ -0,0 +1,205 @@
+.\" Copyright (c) 2008 The Aerospace Corporation
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of its contributors may
+.\" be used to endorse or promote products derived from this software
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 29 2008
+.Dt VARSYM 2
+.Os
+.Sh NAME
+.Nm varsym
+.Nd manipulate variant symlink variables
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In varsym.h
+.Ft int
+.Fn varsym_set "int scope" "id_t which" "const char *name" "const char *data"
+.Ft int
+.Fn varsym_get "int scope" "id_t which" "const char *name" "const char *buf" "size_t *size"
+.Ft int
+.Fn varsym_list "int scope" "id_t which" "const char *buf" "size_t *size"
+.Sh DESCRIPTION
+The
+.Fn varsym_set
+function
+sets the variable
+.Fa name
+in the object specifed by
+.Fa scope
+and
+.Fa which
+to the value in the null-terminated string pointed to by
+.Fa data .
+If
+.Fa data
+is
+.Dv NULL
+then the variable will be deleted.
+If
+.Fa name
+is
+.Dv NULL
+then all variables will be deleted.
+.Pp
+The
+.Fn varsym_get
+function
+writes the value of the variable
+.Fa name
+in the object specifed by
+.Fa scope
+and
+.Fa which
+to the buffer
+.Fa buf
+as a null-terminated string.
+The number of bytes written to
+.Fa which
+are copied back to the variable pointed to by
+.Fa size.
+.Pp
+The
+.Fn varsym_list
+function
+writes the names and values of variables
+in the object specifed by
+.Fa scope
+and
+.Fa which
+to the buffer
+.Fa buf
+with nulls between each entry and a final null indicating end of list.
+The number of bytes written to
+.Fa which
+are copied back to the variable pointed to by
+.Fa size.
+.Pp
+The
+.Fa scope
+argument may be one of:
+.Bl -tag -width VARSYM_PROC
+.It Dv VARSYM_SYS
+Get or set variables in the global system scope.
+.It Dv VARSYM_PROC
+Get or set variables for the given process.
+.El
+.Pp
+The following
+.Xr sysctl 3
+MIB variables control the operation of variant symlinks:
+.Bl -tag -width vfs.varsym.enable
+.It Va vfs.varsym.enable
+Enables support for variant symlinks when set to a non-zero value.
+Defaults to off.
+.It Va vfs.varsym.allow_default
+If set to a non-zero value, variant symlinks may be created with default
+values to be used if no variable is set.
+These values are specified by placing a colon after the variable name in the
+link.
+For example
+.Va ${VAR:defaultvalue} .
+.Pp
+.Sy WARNING :
+Default values should not be used in any way that will effect the execution
+of setuid programs unless users can not control the values of variant
+symlinks.
+Administrators are advised to disable default value support when user
+control of per-process values is allowed.
+.It Va vfs.varsym.max_proc_setsize
+Limits the number of per-processes variables that can be set.
+The default limit is 32.
+This limit is only enforced if unprivleged control is allowed by
+.Va security.bsd.unprivileged_varsym_set_proc .
+.It Va security.bsd.unprivileged_varsym_set_proc
+If set to a non-zero value, non-root users may set per-process variant symlink
+variables.
+.El
+.Sh RETURN VALUES
+.Rv -std varsym_set varsym_get varsym_list
+.Sh ERRORS
+The
+.Fn varsym_set ,
+.Fn varsym_get ,
+and
+.Fn varsym_list
+functions will fail and take no action if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+An invalid value is passed for
+.Fa scope
+or
+.Fa which .
+.It Bq Er EPERM
+The
+.Fa which
+variable is set to a value other than 0 or the current processes pid when
+.Fa scope
+is
+.Dv VARSYM_PROC .
+.It Bq Er EOVERFLOW
+The buffer passed to
+.Fn varsym_get
+or
+.Fn varsym_list
+is too small for the data to be returned.
+.It Bq Er E2BIG
+For the
+.Fn varsym_set
+function, the maximum number of variant symlinks for this object has been
+reached.
+.It Bq Er ENOENT
+The requested variant symlink variable does not exist.
+.It Bq Er ENOSYS
+The system does not support variant symlinks or the support has been
+disabled by setting the
+.Xr sysctl 3
+MIB
+.Va vfs.varsym.enable
+to 0.
+.It Bq Er EFAULT
+One of buffers is outside the process's allocated address space.
+.It Bq Er ENAMETOOLONG
+The value of
+.Fa name
+is longer than
+.Dv MAXVARSYM_NAME
+or
+the value of
+.Fa data
+is longer than
+.Dv MAXVARSYM_DATA .
+.El
+.Sh SEE ALSO
+.Xr varsym_clear 3
+.Sh HISTORY
+This version of variant symlinks is derived from variant symlink support that
+first appeared in DragonFlyBSD 1.0.
+.Sh BUGS
+The
+.Fa which
+argument is effectivly unused at this time and must be 0 or the current
+processes pid.
Modified: projects/varsym/lib/libutil/login.conf.5
==============================================================================
--- projects/varsym/lib/libutil/login.conf.5 Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/lib/libutil/login.conf.5 Mon Oct 31 23:27:24 2011 (r226973)
@@ -245,6 +245,8 @@ from other means.
.It "timezone string Default value of $TZ environment variable.
.It "umask number 022 Initial umask. Should always have a leading 0 to
ensure octal interpretation.
+.It "varsym list A comma-separated list of variant symlink variables and
+values to which they are to be set.
.It "welcome file /etc/motd File containing welcome message.
.El
.Sh AUTHENTICATION
Modified: projects/varsym/lib/libutil/login_cap.h
==============================================================================
--- projects/varsym/lib/libutil/login_cap.h Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/lib/libutil/login_cap.h Mon Oct 31 23:27:24 2011 (r226973)
@@ -50,7 +50,8 @@
#define LOGIN_SETMAC 0x0100 /* set user default MAC label */
#define LOGIN_SETCPUMASK 0x0200 /* set user cpumask */
#define LOGIN_SETLOGINCLASS 0x0400 /* set login class in the kernel */
-#define LOGIN_SETALL 0x07ff /* set everything */
+#define LOGIN_SETVARSYM 0x0800 /* set process variant symlink vars */
+#define LOGIN_SETALL 0x0fff /* set everything */
#define BI_AUTH "authorize" /* accepted authentication */
#define BI_REJECT "reject" /* rejected authentication */
@@ -118,6 +119,7 @@ const char *login_setcryptfmt(login_cap_
int setclasscontext(const char *, unsigned int);
void setclasscpumask(login_cap_t *);
+void setclassvarsyms(login_cap_t *, const struct passwd *);
int setusercontext(login_cap_t *, const struct passwd *, uid_t, unsigned int);
void setclassresources(login_cap_t *);
void setclassenvironment(login_cap_t *, const struct passwd *, int);
Modified: projects/varsym/lib/libutil/login_class.3
==============================================================================
--- projects/varsym/lib/libutil/login_class.3 Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/lib/libutil/login_class.3 Mon Oct 31 23:27:24 2011 (r226973)
@@ -175,6 +175,9 @@ no action will be taken.
.It LOGIN_SETLOGINCLASS
Set the login class of the current process using
.Xr setloginclass 2 .
+.It LOGIN_SETVARSYM
+Set process scope variant symlink variables using the list type capability
+"varsym=var1=val1,var2=val2..,varN=valN".
.It LOGIN_SETALL
Enables all of the above settings.
.El
@@ -214,6 +217,7 @@ with LOG_ERR priority and directed to th
.Xr setlogin 2 ,
.Xr setloginclass 2 ,
.Xr setuid 2 ,
+.Xr varsym 2 ,
.Xr getcap 3 ,
.Xr initgroups 3 ,
.Xr login_cap 3 ,
Modified: projects/varsym/lib/libutil/login_class.c
==============================================================================
--- projects/varsym/lib/libutil/login_class.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/lib/libutil/login_class.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rtprio.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/varsym.h>
#include <ctype.h>
#include <err.h>
@@ -136,9 +137,15 @@ static struct login_vars {
};
static char *
-substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nlen)
+substvar(const char * var, const struct passwd * pwd)
{
- char *np = NULL;
+ char *np = NULL;
+ int hlen = pwd ? strlen(pwd->pw_dir) : 0;
+ int nlen = pwd ? strlen(pwd->pw_name) : 0;
+ char pch = 0;
+
+ if (hlen && pwd->pw_dir[hlen-1] != '/')
+ ++pch;
if (var != NULL) {
int tildes = 0;
@@ -196,18 +203,12 @@ void
setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths)
{
struct login_vars *vars = paths ? pathvars : envars;
- int hlen = pwd ? strlen(pwd->pw_dir) : 0;
- int nlen = pwd ? strlen(pwd->pw_name) : 0;
- char pch = 0;
-
- if (hlen && pwd->pw_dir[hlen-1] != '/')
- ++pch;
while (vars->tag != NULL) {
const char * var = paths ? login_getpath(lc, vars->tag, NULL)
: login_getcapstr(lc, vars->tag, NULL, NULL);
- char * np = substvar(var, pwd, hlen, pch, nlen);
+ char * np = substvar(var, pwd);
if (np != NULL) {
setenv(vars->var, np, vars->overwrite);
@@ -233,7 +234,7 @@ setclassenvironment(login_cap_t *lc, con
char *np;
*p++ = '\0';
- if ((np = substvar(p, pwd, hlen, pch, nlen)) != NULL) {
+ if ((np = substvar(p, pwd)) != NULL) {
setenv(*set_env, np, 1);
free(np);
}
@@ -347,6 +348,31 @@ setclasscpumask(login_cap_t *lc)
}
+void
+setclassvarsyms(login_cap_t *lc, const struct passwd * pwd)
+{
+ const char **varsyms = login_getcaplist(lc, "varsym", ",");
+
+ if (varsyms != NULL) {
+ while (*varsyms != NULL) {
+ char *p = strchr(*varsyms, '=');
+
+ if (p != NULL) { /* Discard invalid entries */
+ char *np;
+
+ *p++ = '\0';
+ if ((np = substvar(p, pwd)) != NULL) {
+ /* XXX: should we only ignore ENOSYS? */
+ (void)varsym_set(VARSYM_PROC, 0, *varsyms, np);
+ free(np);
+ }
+ }
+ ++varsyms;
+ }
+ }
+}
+
+
/*
* setclasscontext()
*
@@ -400,6 +426,9 @@ setlogincontext(login_cap_t *lc, const s
/* Set cpu affinity */
if (flags & LOGIN_SETCPUMASK)
setclasscpumask(lc);
+ /* Set variant symlink variables */
+ if (flags & LOGIN_SETVARSYM)
+ setclassvarsyms(lc, pwd);
}
return (mymask);
}
Modified: projects/varsym/sys/amd64/conf/GENERIC
==============================================================================
--- projects/varsym/sys/amd64/conf/GENERIC Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/amd64/conf/GENERIC Mon Oct 31 23:27:24 2011 (r226973)
@@ -42,6 +42,7 @@ options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options VARSYM # Variant symlink support
options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
options COMPAT_FREEBSD32 # Compatible with i386 binaries
Modified: projects/varsym/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_misc.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_misc.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <sys/thr.h>
#include <sys/unistd.h>
#include <sys/ucontext.h>
+#include <sys/varsym.h>
#include <sys/vnode.h>
#include <sys/wait.h>
#include <sys/ipc.h>
@@ -2514,6 +2515,92 @@ freebsd32_nmount(struct thread *td,
return error;
}
+#ifdef VARSYM
+int
+freebsd32_varsym_set(struct thread *td, struct freebsd32_varsym_set_args *uap)
+{
+ struct varsym_set_args ap;
+
+ ap.scope = uap->scope;
+ ap.which = (uap->whichlo | ((id_t)uap->whichhi << 32));
+ ap.name = uap->name;
+ ap.data = uap->data;
+
+ return (varsym_set(td, &ap));
+}
+
+
+int
+freebsd32_varsym_get(struct thread *td, struct freebsd32_varsym_get_args *uap)
+{
+ int error;
+ id_t which;
+ size_t bufsize;
+ uint32_t bufsize32;
+
+ which = (uap->whichlo | ((id_t)uap->whichhi << 32));
+
+ if ((error = copyin(uap->size, &bufsize32, sizeof(bufsize32))) != 0)
+ return(error);
+ bufsize = bufsize32;
+
+ if ((error = kern_varsym_get(td, uap->scope, which, uap->name,
+ uap->buf, &bufsize)) != 0)
+ return(error);
+
+ bufsize32 = bufsize;
+ error = copyout(&bufsize32, uap->size, sizeof(bufsize32));
+
+ return(error);
+}
+
+int
+freebsd32_varsym_list(struct thread *td, struct freebsd32_varsym_list_args *uap)
+{
+ int error;
+ id_t which;
+ size_t bufsize;
+ uint32_t bufsize32;
+
+ which = (uap->whichlo | ((id_t)uap->whichhi << 32));
+
+ if ((error = copyin(uap->size, &bufsize32, sizeof(bufsize32))) != 0)
+ return(error);
+ bufsize = bufsize32;
+
+ if ((error = kern_varsym_list(td, uap->scope, which, uap->buf,
+ &bufsize)) != 0)
+ return(error);
+
+ bufsize32 = bufsize;
+ error = copyout(&bufsize32, uap->size, sizeof(bufsize32));
+
+ return(error);
+}
+
+#else /* VARSYM */
+int
+freebsd32_varsym_set(struct thread *td, struct freebsd32_varsym_set_args *uap)
+{
+
+ return (ENOSYS);
+}
+
+int
+freebsd32_varsym_get(struct thread *td, struct freebsd32_varsym_get_args *uap)
+{
+
+ return (ENOSYS);
+}
+
+int
+freebsd32_varsym_list(struct thread *td, struct freebsd32_varsym_list_args *uap)
+{
+
+ return (ENOSYS);
+}
+#endif /* VARSYM */
+
#if 0
int
freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
Modified: projects/varsym/sys/compat/freebsd32/freebsd32_proto.h
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_proto.h Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_proto.h Mon Oct 31 23:27:24 2011 (r226973)
@@ -580,6 +580,28 @@ struct freebsd32_posix_fallocate_args {
char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
};
+struct freebsd32_varsym_set_args {
+ char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)];
+ char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)];
+ char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char data_l_[PADL_(const char *)]; const char * data; char data_r_[PADR_(const char *)];
+};
+struct freebsd32_varsym_get_args {
+ char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)];
+ char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)];
+ char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char size_l_[PADL_(uint32_t *)]; uint32_t * size; char size_r_[PADR_(uint32_t *)];
+};
+struct freebsd32_varsym_list_args {
+ char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)];
+ char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)];
+ char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char size_l_[PADL_(uint32_t *)]; uint32_t * size; char size_r_[PADR_(uint32_t *)];
+};
#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
#define PAD64_REQUIRED
#endif
@@ -690,6 +712,9 @@ int freebsd32_msgctl(struct thread *, st
int freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *);
int freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *);
int freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *);
+int freebsd32_varsym_set(struct thread *, struct freebsd32_varsym_set_args *);
+int freebsd32_varsym_get(struct thread *, struct freebsd32_varsym_get_args *);
+int freebsd32_varsym_list(struct thread *, struct freebsd32_varsym_list_args *);
#ifdef COMPAT_43
@@ -1065,6 +1090,9 @@ int freebsd7_freebsd32_shmctl(struct thr
#define FREEBSD32_SYS_AUE_freebsd32_shmctl AUE_SHMCTL
#define FREEBSD32_SYS_AUE_freebsd32_pselect AUE_SELECT
#define FREEBSD32_SYS_AUE_freebsd32_posix_fallocate AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_varsym_set AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_varsym_get AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_varsym_list AUE_NULL
#undef PAD_
#undef PADL_
Modified: projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h Mon Oct 31 23:27:24 2011 (r226973)
@@ -424,4 +424,7 @@
#define FREEBSD32_SYS_rctl_add_rule 528
#define FREEBSD32_SYS_rctl_remove_rule 529
#define FREEBSD32_SYS_freebsd32_posix_fallocate 530
-#define FREEBSD32_SYS_MAXSYSCALL 532
+#define FREEBSD32_SYS_freebsd32_varsym_set 532
+#define FREEBSD32_SYS_freebsd32_varsym_get 533
+#define FREEBSD32_SYS_freebsd32_varsym_list 534
+#define FREEBSD32_SYS_MAXSYSCALL 535
Modified: projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -555,4 +555,7 @@ const char *freebsd32_syscallnames[] = {
"rctl_remove_rule", /* 529 = rctl_remove_rule */
"freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */
"#531", /* 531 = posix_fadvise */
+ "freebsd32_varsym_set", /* 532 = freebsd32_varsym_set */
+ "freebsd32_varsym_get", /* 533 = freebsd32_varsym_get */
+ "freebsd32_varsym_list", /* 534 = freebsd32_varsym_list */
};
Modified: projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -592,4 +592,7 @@ struct sysent freebsd32_sysent[] = {
{ AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */
{ AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 531 = posix_fadvise */
+ { AS(freebsd32_varsym_set_args), (sy_call_t *)freebsd32_varsym_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_varsym_set */
+ { AS(freebsd32_varsym_get_args), (sy_call_t *)freebsd32_varsym_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = freebsd32_varsym_get */
+ { AS(freebsd32_varsym_list_args), (sy_call_t *)freebsd32_varsym_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = freebsd32_varsym_list */
};
Modified: projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -3034,6 +3034,40 @@ systrace_args(int sysnum, void *params,
*n_args = 5;
break;
}
+ /* freebsd32_varsym_set */
+ case 532: {
+ struct freebsd32_varsym_set_args *p = params;
+ iarg[0] = p->scope; /* int */
+ uarg[1] = p->whichlo; /* uint32_t */
+ uarg[2] = p->whichhi; /* uint32_t */
+ uarg[3] = (intptr_t) p->name; /* const char * */
+ uarg[4] = (intptr_t) p->data; /* const char * */
+ *n_args = 5;
+ break;
+ }
+ /* freebsd32_varsym_get */
+ case 533: {
+ struct freebsd32_varsym_get_args *p = params;
+ iarg[0] = p->scope; /* int */
+ uarg[1] = p->whichlo; /* uint32_t */
+ uarg[2] = p->whichhi; /* uint32_t */
+ uarg[3] = (intptr_t) p->name; /* const char * */
+ uarg[4] = (intptr_t) p->buf; /* char * */
+ uarg[5] = (intptr_t) p->size; /* uint32_t * */
+ *n_args = 6;
+ break;
+ }
+ /* freebsd32_varsym_list */
+ case 534: {
+ struct freebsd32_varsym_list_args *p = params;
+ iarg[0] = p->scope; /* int */
+ uarg[1] = p->whichlo; /* uint32_t */
+ uarg[2] = p->whichhi; /* uint32_t */
+ uarg[3] = (intptr_t) p->buf; /* char * */
+ uarg[4] = (intptr_t) p->size; /* uint32_t * */
+ *n_args = 5;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8093,6 +8127,75 @@ systrace_setargdesc(int sysnum, int ndx,
break;
};
break;
+ /* freebsd32_varsym_set */
+ case 532:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "const char *";
+ break;
+ case 4:
+ p = "const char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* freebsd32_varsym_get */
+ case 533:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "const char *";
+ break;
+ case 4:
+ p = "char *";
+ break;
+ case 5:
+ p = "uint32_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* freebsd32_varsym_list */
+ case 534:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "char *";
+ break;
+ case 4:
+ p = "uint32_t *";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
Modified: projects/varsym/sys/compat/freebsd32/syscalls.master
==============================================================================
--- projects/varsym/sys/compat/freebsd32/syscalls.master Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/compat/freebsd32/syscalls.master Mon Oct 31 23:27:24 2011 (r226973)
@@ -992,3 +992,13 @@
uint32_t offset1, uint32_t offset2,\
uint32_t len1, uint32_t len2); }
531 AUE_NULL UNIMPL posix_fadvise
+532 AUE_NULL STD { int freebsd32_varsym_set(int scope, \
+ uint32_t whichlo, uint32_t whichhi, \
+ const char *name, const char *data); }
+533 AUE_NULL STD { int freebsd32_varsym_get(int scope, \
+ uint32_t whichlo, uint32_t whichhi, \
+ const char *name, \
+ char *buf, uint32_t *size); }
+534 AUE_NULL STD { int freebsd32_varsym_list(int scope, \
+ uint32_t whichlo, uint32_t whichhi, \
+ char *buf, uint32_t *size); }
Modified: projects/varsym/sys/conf/files
==============================================================================
--- projects/varsym/sys/conf/files Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/conf/files Mon Oct 31 23:27:24 2011 (r226973)
@@ -2358,6 +2358,7 @@ kern/kern_time.c standard
kern/kern_timeout.c standard
kern/kern_umtx.c standard
kern/kern_uuid.c standard
+kern/kern_varsym.c standard
kern/kern_xxx.c standard
kern/link_elf.c standard
kern/linker_if.m standard
Modified: projects/varsym/sys/conf/options
==============================================================================
--- projects/varsym/sys/conf/options Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/conf/options Mon Oct 31 23:27:24 2011 (r226973)
@@ -183,6 +183,7 @@ SYSVSEM opt_sysvipc.h
SYSVSHM opt_sysvipc.h
SW_WATCHDOG opt_watchdog.h
TURNSTILE_PROFILING
+VARSYM
VFS_AIO
VERBOSE_SYSINIT opt_global.h
WLCACHE opt_wavelan.h
Modified: projects/varsym/sys/kern/init_sysent.c
==============================================================================
--- projects/varsym/sys/kern/init_sysent.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/kern/init_sysent.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -566,4 +566,7 @@ struct sysent sysent[] = {
{ AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */
{ AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = posix_fallocate */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 531 = posix_fadvise */
+ { AS(varsym_set_args), (sy_call_t *)sys_varsym_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = varsym_set */
+ { AS(varsym_get_args), (sy_call_t *)sys_varsym_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = varsym_get */
+ { AS(varsym_list_args), (sy_call_t *)sys_varsym_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = varsym_list */
};
Modified: projects/varsym/sys/kern/kern_exec.c
==============================================================================
--- projects/varsym/sys/kern/kern_exec.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/kern/kern_exec.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -729,6 +729,14 @@ interpret:
change_svgid(newcred, newcred->cr_gid);
p->p_ucred = newcred;
newcred = NULL;
+
+#ifdef VARSYM
+ /*
+ * Clear local varsym variables.
+ * Do not clear privleged varsym variables.
+ */
+ varsymset_clean(&p->p_varsymset);
+#endif
} else {
if (oldcred->cr_uid == oldcred->cr_ruid &&
oldcred->cr_gid == oldcred->cr_rgid)
Modified: projects/varsym/sys/kern/kern_fork.c
==============================================================================
--- projects/varsym/sys/kern/kern_fork.c Mon Oct 31 21:05:19 2011 (r226972)
+++ projects/varsym/sys/kern/kern_fork.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -426,6 +426,14 @@ do_fork(struct thread *td, int flags, st
else
newsigacts = sigacts_alloc();
+#ifdef VARSYM
+ /*
+ * Initialize and copy varsyms
+ */
+ varsymset_init(&p2->p_varsymset, &p1->p_varsymset);
+ varsymset_init(&p2->p_varsymset_priv, &p1->p_varsymset_priv);
+#endif
+
/*
* Copy filedesc.
*/
Added: projects/varsym/sys/kern/kern_varsym.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/varsym/sys/kern/kern_varsym.c Mon Oct 31 23:27:24 2011 (r226973)
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved.
+ * Copyright (c) 2007-2009 The Aerospace Corporation. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon at backplane.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDERS 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.
+ *
+ * $FreeBSD$
+ * $DragonFly: src/sys/kern/kern_varsym.c,v 1.6 2005/01/14 02:25:08 joerg Exp $
+ */
+
+/*
+ * This module implements variable storage and management for variant
+ * symlinks. These variables may also be used for general purposes.
+ */
+
+#include "opt_varsym.h"
+
+#include <sys/param.h>
+#include <sys/priv.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/ucred.h>
+#include <sys/resourcevar.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/refcount.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/varsym.h>
+#include <sys/sysproto.h>
+
+#ifdef VARSYM
+
+SYSCTL_NODE(_vfs, OID_AUTO, varsym, CTLFLAG_RD, NULL,
+ "Variant symlink managment");
+
+int varsym_enable = 0;
+SYSCTL_INT(_vfs_varsym, OID_AUTO, enable, CTLFLAG_RW, &varsym_enable, 0,
+ "Enable Variant Symlinks");
+TUNABLE_INT("vfs.varsym.enable",
+ &varsym_enable);
+
+static int varsym_allow_default = 0;
+SYSCTL_INT(_vfs_varsym, OID_AUTO, allow_default, CTLFLAG_RW,
+ &varsym_allow_default, 0,
+ "allow variables to have default values");
+TUNABLE_INT("vfs.varsym.allow_default",
+ &varsym_allow_default);
+
+static int varsym_max_proc_setsize = 32;
+SYSCTL_INT(_vfs_varsym, OID_AUTO, max_proc_setsize, CTLFLAG_RW,
+ &varsym_max_proc_setsize, 0,
+ "maximum number of varsym variables on a process");
+TUNABLE_INT("vfs.varsym_max_proc_setsize",
+ &varsym_max_proc_setsize);
+
+static int unprivileged_varsym_set_proc = 1;
+SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_varsym_set_proc, CTLFLAG_RW,
+ &unprivileged_varsym_set_proc, 0,
+ "allow unprivileged users to set per-process varsym variables");
+TUNABLE_INT("security.bsd.unprivileged_varsym_set_proc",
+ &unprivileged_varsym_set_proc);
+
+MALLOC_DEFINE(M_VARSYM, "varsym", "variable sets for variant symlinks");
+static struct mtx varsym_mutex;
+static struct varsymset varsymset_sys;
+
+static int varsymmake(int scope, const char *name, const char *data);
+static void varsymdrop(varsym_t var);
+static struct varsyment * varsymlookup(struct varsymset *vss, const char *name,
+ int namelen);
+static int varsym_clear(struct thread *td, int scope, id_t which);
+static int vss2buf(struct varsymset *vss, char *buf, int *bytes,
+ int maxsize);
+static varsym_t varsymfind(int scope, const char *name, int namelen);
+
+/*
+ * Initialize the variant symlink subsystem
+ */
+static void
+varsym_sysinit(void *dummy)
+{
+ mtx_init(&varsym_mutex, "varsym", NULL, MTX_DEF);
+ varsymset_init(&varsymset_sys, NULL);
+}
+SYSINIT(announce, SI_SUB_INTRINSIC, SI_ORDER_FIRST, varsym_sysinit, NULL);
+
+/*
+ * Initialize the varsymset for proc0
+ */
+static void
+varsym_p0init(void *dummy)
+{
+ PROC_LOCK(&proc0);
+ varsymset_init(&proc0.p_varsymset, NULL);
+ varsymset_init(&proc0.p_varsymset_priv, NULL);
+ PROC_UNLOCK(&proc0);
+}
+SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_SECOND, varsym_p0init, NULL);
+
+/*
+ * varsymreplace() - called from namei
+ *
+ * Do variant symlink variable substitution
+ */
+int
+varsymreplace(char *cp, int linklen, int maxlen)
+{
+ int rlen;
+ int xlen;
+ int nlen;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list