1139743Simp/*-
243412Snewton * Copyright (c) 1998 Mark Newton
343412Snewton * Copyright (c) 1994 Christos Zoulas
443412Snewton * All rights reserved.
543412Snewton *
643412Snewton * Redistribution and use in source and binary forms, with or without
743412Snewton * modification, are permitted provided that the following conditions
843412Snewton * are met:
943412Snewton * 1. Redistributions of source code must retain the above copyright
1043412Snewton *    notice, this list of conditions and the following disclaimer.
1143412Snewton * 2. Redistributions in binary form must reproduce the above copyright
1243412Snewton *    notice, this list of conditions and the following disclaimer in the
1343412Snewton *    documentation and/or other materials provided with the distribution.
1443412Snewton * 3. The name of the author may not be used to endorse or promote products
1543412Snewton *    derived from this software without specific prior written permission
1643412Snewton *
1743412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1843412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1943412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2043412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2143412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2243412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2643412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743412Snewton */
2843412Snewton
29116174Sobrien#include <sys/cdefs.h>
30116174Sobrien__FBSDID("$FreeBSD$");
31116174Sobrien
3243412Snewton#include <sys/param.h>
3343412Snewton#include <sys/systm.h>
3443412Snewton#include <sys/proc.h>
3543412Snewton#include <sys/stat.h>
3643412Snewton#include <sys/filedesc.h>
37274476Skib#include <sys/fcntl.h>
3891386Srobert#include <sys/jail.h>
3943412Snewton#include <sys/kernel.h>
40141486Sjhb#include <sys/malloc.h>
41195458Strasz#include <sys/namei.h>
4243412Snewton#include <sys/unistd.h>
4354305Snewton#include <sys/time.h>
44141486Sjhb#include <sys/syscallsubr.h>
4554305Snewton#include <sys/sysctl.h>
4654305Snewton#include <sys/sysproto.h>
47115550Sphk#include <sys/un.h>
4843412Snewton
4943412Snewton#include <vm/vm.h>
5054305Snewton
5143412Snewton#include <netinet/in.h>
5243412Snewton
5365302Sobrien#include <compat/svr4/svr4.h>
5465302Sobrien#include <compat/svr4/svr4_types.h>
5565302Sobrien#include <compat/svr4/svr4_signal.h>
5665302Sobrien#include <compat/svr4/svr4_proto.h>
5765302Sobrien#include <compat/svr4/svr4_util.h>
5865302Sobrien#include <compat/svr4/svr4_stat.h>
5965302Sobrien#include <compat/svr4/svr4_ustat.h>
6065302Sobrien#include <compat/svr4/svr4_utsname.h>
6165302Sobrien#include <compat/svr4/svr4_systeminfo.h>
6265302Sobrien#include <compat/svr4/svr4_socket.h>
6365302Sobrien#include <compat/svr4/svr4_time.h>
6443412Snewton#if defined(NOTYET)
6543412Snewton#include "svr4_fuser.h"
6643412Snewton#endif
6743412Snewton
6843412Snewton#ifdef sparc
6943412Snewton/*
7043412Snewton * Solaris-2.4 on the sparc has the old stat call using the new
7143412Snewton * stat data structure...
7243412Snewton */
7343412Snewton# define SVR4_NO_OSTAT
7443412Snewton#endif
7543412Snewton
7643412Snewtonstruct svr4_ustat_args {
7743412Snewton	svr4_dev_t		dev;
7843412Snewton	struct svr4_ustat * name;
7943412Snewton};
8043412Snewton
8192761Salfredstatic void bsd_to_svr4_xstat(struct stat *, struct svr4_xstat *);
8292761Salfredstatic void bsd_to_svr4_stat64(struct stat *, struct svr4_stat64 *);
8392761Salfredint svr4_ustat(struct thread *, struct svr4_ustat_args *);
8492761Salfredstatic int svr4_to_bsd_pathconf(int);
8543412Snewton
8643412Snewton/*
8743412Snewton * SVR4 uses named pipes as named sockets, so we tell programs
8843412Snewton * that sockets are named pipes with mode 0
8943412Snewton */
9043412Snewton#define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
9143412Snewton
9243412Snewton
9343412Snewton#ifndef SVR4_NO_OSTAT
9492761Salfredstatic void bsd_to_svr4_stat(struct stat *, struct svr4_stat *);
9543412Snewton
9643412Snewtonstatic void
9743412Snewtonbsd_to_svr4_stat(st, st4)
9843412Snewton	struct stat		*st;
9943412Snewton	struct svr4_stat 	*st4;
10043412Snewton{
10143412Snewton	memset(st4, 0, sizeof(*st4));
10243412Snewton	st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
10343412Snewton	st4->st_ino = st->st_ino;
10443412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
10543412Snewton	st4->st_nlink = st->st_nlink;
10643412Snewton	st4->st_uid = st->st_uid;
10743412Snewton	st4->st_gid = st->st_gid;
10843412Snewton	st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
10943412Snewton	st4->st_size = st->st_size;
110205792Sed	st4->st_atim = st->st_atim.tv_sec;
111205792Sed	st4->st_mtim = st->st_mtim.tv_sec;
112205792Sed	st4->st_ctim = st->st_ctim.tv_sec;
11343412Snewton}
11443412Snewton#endif
11543412Snewton
11643412Snewton
11743412Snewtonstatic void
11843412Snewtonbsd_to_svr4_xstat(st, st4)
11943412Snewton	struct stat		*st;
12043412Snewton	struct svr4_xstat	*st4;
12143412Snewton{
12243412Snewton	memset(st4, 0, sizeof(*st4));
12343412Snewton	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
12443412Snewton	st4->st_ino = st->st_ino;
12543412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
12643412Snewton	st4->st_nlink = st->st_nlink;
12743412Snewton	st4->st_uid = st->st_uid;
12843412Snewton	st4->st_gid = st->st_gid;
12943412Snewton	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
13043412Snewton	st4->st_size = st->st_size;
131205792Sed	st4->st_atim = st->st_atim;
132205792Sed	st4->st_mtim = st->st_mtim;
133205792Sed	st4->st_ctim = st->st_ctim;
13443412Snewton	st4->st_blksize = st->st_blksize;
13543412Snewton	st4->st_blocks = st->st_blocks;
13643412Snewton	strcpy(st4->st_fstype, "unknown");
13743412Snewton}
13843412Snewton
13943412Snewton
14043412Snewtonstatic void
14143412Snewtonbsd_to_svr4_stat64(st, st4)
14243412Snewton	struct stat		*st;
14343412Snewton	struct svr4_stat64	*st4;
14443412Snewton{
14543412Snewton	memset(st4, 0, sizeof(*st4));
14643412Snewton	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
14743412Snewton	st4->st_ino = st->st_ino;
14843412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
14943412Snewton	st4->st_nlink = st->st_nlink;
15043412Snewton	st4->st_uid = st->st_uid;
15143412Snewton	st4->st_gid = st->st_gid;
15243412Snewton	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
15343412Snewton	st4->st_size = st->st_size;
154205792Sed	st4->st_atim = st->st_atim;
155205792Sed	st4->st_mtim = st->st_mtim;
156205792Sed	st4->st_ctim = st->st_ctim;
15743412Snewton	st4->st_blksize = st->st_blksize;
15843412Snewton	st4->st_blocks = st->st_blocks;
15943412Snewton	strcpy(st4->st_fstype, "unknown");
16043412Snewton}
16143412Snewton
16243412Snewtonint
16383366Sjuliansvr4_sys_stat(td, uap)
16483366Sjulian	struct thread *td;
16543412Snewton	struct svr4_sys_stat_args *uap;
16643412Snewton{
167141486Sjhb	struct svr4_stat svr4_st;
168141486Sjhb	struct stat st;
169141486Sjhb	char *path;
170141486Sjhb	int error;
17143412Snewton
172141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
17343412Snewton
174274476Skib	error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL);
175141486Sjhb	free(path, M_TEMP);
176141486Sjhb	if (error)
177141486Sjhb		return (error);
17843412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
17943412Snewton
18043412Snewton	if (S_ISSOCK(st.st_mode))
181107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
18243412Snewton
183141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
18443412Snewton}
18543412Snewton
18643412Snewton
18743412Snewtonint
18883366Sjuliansvr4_sys_lstat(td, uap)
189193014Sdelphij	struct thread *td;
19043412Snewton	struct svr4_sys_lstat_args *uap;
19143412Snewton{
192141486Sjhb	struct svr4_stat svr4_st;
193141486Sjhb	struct stat st;
194141486Sjhb	char *path;
195141486Sjhb	int error;
19643412Snewton
197141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
19843412Snewton
199274476Skib	error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path,
200274476Skib	    UIO_SYSSPACE, &st, NULL);
201141486Sjhb	free(path, M_TEMP);
202141486Sjhb	if (error)
203141486Sjhb		return (error);
20443412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
20543412Snewton
20643412Snewton	if (S_ISSOCK(st.st_mode))
207107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
20843412Snewton
209141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
21043412Snewton}
21143412Snewton
21243412Snewton
21343412Snewtonint
21483366Sjuliansvr4_sys_fstat(td, uap)
215193014Sdelphij	struct thread *td;
21643412Snewton	struct svr4_sys_fstat_args *uap;
21743412Snewton{
218141486Sjhb	struct svr4_stat svr4_st;
219141486Sjhb	struct stat st;
220141486Sjhb	int error;
22143412Snewton
22243412Snewton
223141486Sjhb	error = kern_fstat(td, uap->fd, &st);
224141486Sjhb	if (error)
225141486Sjhb		return (error);
22643412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
227141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
22843412Snewton}
22943412Snewton
23043412Snewton
23143412Snewtonint
23283366Sjuliansvr4_sys_xstat(td, uap)
233193014Sdelphij	struct thread *td;
23443412Snewton	struct svr4_sys_xstat_args *uap;
23543412Snewton{
236141486Sjhb	struct svr4_xstat svr4_st;
237141486Sjhb	struct stat st;
238141486Sjhb	char *path;
239141486Sjhb	int error;
24043412Snewton
241141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
24243412Snewton
243274476Skib	error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL);
244141486Sjhb	free(path, M_TEMP);
245141486Sjhb	if (error)
246141486Sjhb		return (error);
24743412Snewton
24843412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
24943412Snewton
25043412Snewton#if defined(SOCKET_NOTYET)
25143412Snewton	if (S_ISSOCK(st.st_mode))
252107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
25343412Snewton#endif
25443412Snewton
255141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
25643412Snewton}
25743412Snewton
25843412Snewtonint
25983366Sjuliansvr4_sys_lxstat(td, uap)
260193014Sdelphij	struct thread *td;
26143412Snewton	struct svr4_sys_lxstat_args *uap;
26243412Snewton{
263141486Sjhb	struct svr4_xstat svr4_st;
264141486Sjhb	struct stat st;
265141486Sjhb	char *path;
266141486Sjhb	int error;
26743412Snewton
268141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
26943412Snewton
270274476Skib	error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path,
271274476Skib	    UIO_SYSSPACE, &st, NULL);
272141486Sjhb	free(path, M_TEMP);
273141486Sjhb	if (error)
274141486Sjhb		return (error);
27543412Snewton
27643412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
27743412Snewton
27843412Snewton#if defined(SOCKET_NOTYET)
27943412Snewton	if (S_ISSOCK(st.st_mode))
280107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
28143412Snewton#endif
282141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
28343412Snewton}
28443412Snewton
28543412Snewton
28643412Snewtonint
28783366Sjuliansvr4_sys_fxstat(td, uap)
288193014Sdelphij	struct thread *td;
28943412Snewton	struct svr4_sys_fxstat_args *uap;
29043412Snewton{
291141486Sjhb	struct svr4_xstat svr4_st;
292141486Sjhb	struct stat st;
293141486Sjhb	int error;
29443412Snewton
29543412Snewton
296141486Sjhb	error = kern_fstat(td, uap->fd, &st);
297141486Sjhb	if (error)
298141486Sjhb		return (error);
29943412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
300141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
30143412Snewton}
30243412Snewton
30343412Snewtonint
30483366Sjuliansvr4_sys_stat64(td, uap)
305193014Sdelphij	struct thread *td;
30643412Snewton	struct svr4_sys_stat64_args *uap;
30743412Snewton{
308141486Sjhb	struct svr4_stat64 svr4_st;
309141486Sjhb	struct stat st;
310141486Sjhb	char *path;
311141486Sjhb	int error;
31243412Snewton
313141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
31443412Snewton
315274476Skib	error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL);
316141486Sjhb	free(path, M_TEMP);
317141486Sjhb	if (error)
318141486Sjhb		return (error);
31943412Snewton
32043412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
32143412Snewton
32243412Snewton	if (S_ISSOCK(st.st_mode))
323107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
32443412Snewton
325141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
32643412Snewton}
32743412Snewton
32843412Snewton
32943412Snewtonint
33083366Sjuliansvr4_sys_lstat64(td, uap)
331193014Sdelphij	struct thread *td;
33243412Snewton	struct svr4_sys_lstat64_args *uap;
33343412Snewton{
334141486Sjhb	struct svr4_stat64 svr4_st;
335141486Sjhb	struct stat st;
336141486Sjhb	char *path;
337141486Sjhb	int error;
33843412Snewton
339141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
34043412Snewton
341274476Skib	error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path,
342274476Skib	    UIO_SYSSPACE, &st, NULL);
343141486Sjhb	free(path, M_TEMP);
344141486Sjhb	if (error)
345141486Sjhb		return (error);
34643412Snewton
34743412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
34843412Snewton
34943412Snewton	if (S_ISSOCK(st.st_mode))
350107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
35143412Snewton
352141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
35343412Snewton}
35443412Snewton
35543412Snewton
35643412Snewtonint
35783366Sjuliansvr4_sys_fstat64(td, uap)
358193014Sdelphij	struct thread *td;
35943412Snewton	struct svr4_sys_fstat64_args *uap;
36043412Snewton{
361141486Sjhb	struct svr4_stat64 svr4_st;
362141486Sjhb	struct stat st;
363141486Sjhb	int error;
36443412Snewton
365141486Sjhb	error = kern_fstat(td, uap->fd, &st);
366141486Sjhb	if (error)
367141486Sjhb		return (error);
36843412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
369141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
37043412Snewton}
37143412Snewton
37243412Snewton
37343412Snewtonint
37483366Sjuliansvr4_ustat(td, uap)
375193014Sdelphij	struct thread *td;
37643412Snewton	struct svr4_ustat_args *uap;
37743412Snewton{
37843412Snewton	struct svr4_ustat	us;
37943412Snewton	int			error;
38043412Snewton
38143412Snewton	memset(&us, 0, sizeof us);
38243412Snewton
38343412Snewton	/*
38443412Snewton         * XXX: should set f_tfree and f_tinode at least
38543412Snewton         * How do we translate dev -> fstat? (and then to svr4_ustat)
38643412Snewton         */
387107849Salfred	if ((error = copyout(&us, uap->name, sizeof us)) != 0)
38843412Snewton		return (error);
38943412Snewton
39043412Snewton	return 0;
39143412Snewton}
39243412Snewton
393193066Sjamie/*extern char ostype[], osrelease[], version[], machine[];*/
39443412Snewton
39543412Snewtonint
39683366Sjuliansvr4_sys_uname(td, uap)
397193014Sdelphij	struct thread *td;
39843412Snewton	struct svr4_sys_uname_args *uap;
39943412Snewton{
40043412Snewton	struct svr4_utsname	sut;
40143412Snewton
40243412Snewton	memset(&sut, 0, sizeof(sut));
40343412Snewton
404105360Srobert	strlcpy(sut.sysname, ostype, sizeof(sut.sysname));
40591392Srobert	getcredhostname(td->td_ucred, sut.nodename, sizeof(sut.nodename));
406105360Srobert	strlcpy(sut.release, osrelease, sizeof(sut.release));
407105360Srobert	strlcpy(sut.version, version, sizeof(sut.version));
408105360Srobert	strlcpy(sut.machine, machine, sizeof(sut.machine));
40943412Snewton
410107849Salfred	return copyout((caddr_t) &sut, (caddr_t) uap->name,
41143412Snewton		       sizeof(struct svr4_utsname));
41243412Snewton}
41343412Snewton
41443412Snewtonint
41583366Sjuliansvr4_sys_systeminfo(td, uap)
41683366Sjulian	struct thread *td;
41743412Snewton	struct svr4_sys_systeminfo_args *uap;
41843412Snewton{
41949264Snewton	char		*str = NULL;
42049264Snewton	int		error = 0;
42183366Sjulian	register_t	*retval = td->td_retval;
422194090Sjamie	u_long		hostid;
42349264Snewton	size_t		len = 0;
424193066Sjamie	char		buf[MAXHOSTNAMELEN];
425107849Salfred	u_int		rlen = uap->len;
42643412Snewton
427107849Salfred	switch (uap->what) {
42843412Snewton	case SVR4_SI_SYSNAME:
42943412Snewton		str = ostype;
43043412Snewton		break;
43143412Snewton
43243412Snewton	case SVR4_SI_HOSTNAME:
433193066Sjamie		getcredhostname(td->td_ucred, buf, sizeof(buf));
434193066Sjamie		str = buf;
43543412Snewton		break;
43643412Snewton
43743412Snewton	case SVR4_SI_RELEASE:
43843412Snewton		str = osrelease;
43943412Snewton		break;
44043412Snewton
44143412Snewton	case SVR4_SI_VERSION:
44243412Snewton		str = version;
44343412Snewton		break;
44443412Snewton
44543412Snewton	case SVR4_SI_MACHINE:
44643412Snewton		str = machine;
44743412Snewton		break;
44843412Snewton
44943412Snewton	case SVR4_SI_ARCHITECTURE:
45043412Snewton		str = machine;
45143412Snewton		break;
45243412Snewton
453193017Sdelphij	case SVR4_SI_ISALIST:
454193017Sdelphij#if defined(__sparc__)
455193017Sdelphij		str = "sparcv9 sparcv9-fsmuld sparcv8 sparcv8-fsmuld sparcv7 sparc";
456193017Sdelphij#elif defined(__i386__)
457193017Sdelphij		str = "i386";
458193017Sdelphij#elif defined(__amd64__)
459193017Sdelphij		str = "amd64";
460193017Sdelphij#else
461193017Sdelphij		str = "unknown";
462193017Sdelphij#endif
463193017Sdelphij		break;
464193017Sdelphij
46543412Snewton	case SVR4_SI_HW_SERIAL:
466194090Sjamie		getcredhostid(td->td_ucred, &hostid);
467194090Sjamie		snprintf(buf, sizeof(buf), "%lu", hostid);
468193016Sdelphij		str = buf;
46943412Snewton		break;
47043412Snewton
47143412Snewton	case SVR4_SI_HW_PROVIDER:
47243412Snewton		str = ostype;
47343412Snewton		break;
47443412Snewton
47543412Snewton	case SVR4_SI_SRPC_DOMAIN:
476194090Sjamie		getcreddomainname(td->td_ucred, buf, sizeof(buf));
477193066Sjamie		str = buf;
47843412Snewton		break;
47943412Snewton
48043412Snewton	case SVR4_SI_PLATFORM:
481193017Sdelphij#if defined(__i386__)
48243412Snewton		str = "i86pc";
48343412Snewton#else
48443412Snewton		str = "unknown";
48543412Snewton#endif
48643412Snewton		break;
48743412Snewton
48843412Snewton	case SVR4_SI_KERB_REALM:
48943412Snewton		str = "unsupported";
49043412Snewton		break;
49143412Snewton#if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
49243412Snewton	case SVR4_SI_SET_HOSTNAME:
49343412Snewton		name = KERN_HOSTNAME;
494107849Salfred		return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
49543412Snewton
49643412Snewton	case SVR4_SI_SET_SRPC_DOMAIN:
49743412Snewton		name = KERN_NISDOMAINNAME;
498107849Salfred		return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
49943412Snewton#else
50043412Snewton	case SVR4_SI_SET_HOSTNAME:
50143412Snewton        case SVR4_SI_SET_SRPC_DOMAIN:
50243412Snewton		/* FALLTHROUGH */
50343412Snewton#endif
50443412Snewton	case SVR4_SI_SET_KERB_REALM:
50543412Snewton		return 0;
50643412Snewton
50743412Snewton	default:
508107849Salfred		DPRINTF(("Bad systeminfo command %d\n", uap->what));
50943412Snewton		return ENOSYS;
51043412Snewton	}
51143412Snewton
51243412Snewton	if (str) {
51343412Snewton		len = strlen(str) + 1;
51443412Snewton		if (len > rlen)
51543412Snewton			len = rlen;
51643412Snewton
517107849Salfred		if (uap->buf) {
518107849Salfred			error = copyout(str, uap->buf, len);
51943412Snewton			if (error)
52043412Snewton				return error;
52143412Snewton			/* make sure we are NULL terminated */
52243412Snewton			buf[0] = '\0';
523107849Salfred			error = copyout(buf, &(uap->buf[len - 1]), 1);
52443412Snewton		}
52543412Snewton		else
52643412Snewton			error = 0;
52743412Snewton	}
52843412Snewton	/* XXX NetBSD has hostname setting stuff here.  Why would an emulator
52943412Snewton	   want to do that? */
53043412Snewton
53143412Snewton	*retval = len;
53243412Snewton	return error;
53343412Snewton}
53443412Snewton
53543412Snewtonint
53683366Sjuliansvr4_sys_utssys(td, uap)
537193014Sdelphij	struct thread *td;
53843412Snewton	struct svr4_sys_utssys_args *uap;
53943412Snewton{
540107849Salfred	switch (uap->sel) {
54143412Snewton	case 0:		/* uname(2)  */
54243412Snewton		{
54343412Snewton			struct svr4_sys_uname_args ua;
544107849Salfred			ua.name = uap->a1;
54583366Sjulian			return svr4_sys_uname(td, &ua);
54643412Snewton		}
54743412Snewton
54843412Snewton	case 2:		/* ustat(2)  */
54943412Snewton		{
55043412Snewton			struct svr4_ustat_args ua;
551107849Salfred			ua.dev = (svr4_dev_t) uap->a2;
552107849Salfred			ua.name = uap->a1;
55383366Sjulian			return svr4_ustat(td, &ua);
55443412Snewton		}
55543412Snewton
55643412Snewton	case 3:		/* fusers(2) */
55743412Snewton		return ENOSYS;
55843412Snewton
55943412Snewton	default:
56043412Snewton		return ENOSYS;
56143412Snewton	}
56243412Snewton	return ENOSYS;
56343412Snewton}
56443412Snewton
56543412Snewton
56643412Snewtonint
56783366Sjuliansvr4_sys_utime(td, uap)
568193014Sdelphij	struct thread *td;
56943412Snewton	struct svr4_sys_utime_args *uap;
57043412Snewton{
57143412Snewton	struct svr4_utimbuf ub;
572141486Sjhb	struct timeval tbuf[2], *tp;
573141486Sjhb	char *path;
57443412Snewton	int error;
575141486Sjhb
576107849Salfred	if (uap->ubuf != NULL) {
577141486Sjhb		error = copyin(uap->ubuf, &ub, sizeof(ub));
578141486Sjhb		if (error)
579141486Sjhb			return (error);
58043412Snewton		tbuf[0].tv_sec = ub.actime;
58143412Snewton		tbuf[0].tv_usec = 0;
58243412Snewton		tbuf[1].tv_sec = ub.modtime;
58343412Snewton		tbuf[1].tv_usec = 0;
584141486Sjhb		tp = tbuf;
585141486Sjhb	} else
586141486Sjhb		tp = NULL;
587141486Sjhb
588141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
589274476Skib	error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE,
590274476Skib	    tp, UIO_SYSSPACE);
591141486Sjhb	free(path, M_TEMP);
592141486Sjhb	return (error);
59343412Snewton}
59443412Snewton
59543412Snewton
59643412Snewtonint
59783366Sjuliansvr4_sys_utimes(td, uap)
598193014Sdelphij	struct thread *td;
59943412Snewton	struct svr4_sys_utimes_args *uap;
60043412Snewton{
601141486Sjhb	char *path;
602141486Sjhb	int error;
603141486Sjhb
604141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
605274476Skib	error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE,
606274476Skib	    uap->tptr, UIO_USERSPACE);
607141486Sjhb	free(path, M_TEMP);
608141486Sjhb	return (error);
60943412Snewton}
61043412Snewton
61143412Snewtonstatic int
61243412Snewtonsvr4_to_bsd_pathconf(name)
61343412Snewton	int name;
61443412Snewton{
61543412Snewton	switch (name) {
61643412Snewton	case SVR4_PC_LINK_MAX:
61743412Snewton	    	return _PC_LINK_MAX;
61843412Snewton
61943412Snewton	case SVR4_PC_MAX_CANON:
62043412Snewton		return _PC_MAX_CANON;
62143412Snewton
62243412Snewton	case SVR4_PC_MAX_INPUT:
62343412Snewton		return _PC_MAX_INPUT;
62443412Snewton
62543412Snewton	case SVR4_PC_NAME_MAX:
62643412Snewton		return _PC_NAME_MAX;
62743412Snewton
62843412Snewton	case SVR4_PC_PATH_MAX:
62943412Snewton		return _PC_PATH_MAX;
63043412Snewton
63143412Snewton	case SVR4_PC_PIPE_BUF:
63243412Snewton		return _PC_PIPE_BUF;
63343412Snewton
63443412Snewton	case SVR4_PC_NO_TRUNC:
63543412Snewton		return _PC_NO_TRUNC;
63643412Snewton
63743412Snewton	case SVR4_PC_VDISABLE:
63843412Snewton		return _PC_VDISABLE;
63943412Snewton
64043412Snewton	case SVR4_PC_CHOWN_RESTRICTED:
64143412Snewton		return _PC_CHOWN_RESTRICTED;
64243412Snewton	case SVR4_PC_SYNC_IO:
64343412Snewton#if defined(_PC_SYNC_IO)
64443412Snewton		return _PC_SYNC_IO;
64543412Snewton#else
64643412Snewton		return 0;
64743412Snewton#endif
64843412Snewton	case SVR4_PC_ASYNC_IO:
64943412Snewton	case SVR4_PC_PRIO_IO:
65043412Snewton		/* Not supported */
65143412Snewton		return 0;
65243412Snewton
65343412Snewton	default:
65443412Snewton		/* Invalid */
65543412Snewton		return -1;
65643412Snewton	}
65743412Snewton}
65843412Snewton
65943412Snewton
66043412Snewtonint
66183366Sjuliansvr4_sys_pathconf(td, uap)
662193014Sdelphij	struct thread *td;
66343412Snewton	struct svr4_sys_pathconf_args *uap;
66443412Snewton{
665141486Sjhb	char *path;
666141486Sjhb	int error, name;
66743412Snewton
668141486Sjhb	name = svr4_to_bsd_pathconf(uap->name);
66943412Snewton
670141486Sjhb	switch (name) {
67143412Snewton	case -1:
672141486Sjhb		td->td_retval[0] = -1;
673141486Sjhb		return (EINVAL);
67443412Snewton	case 0:
675141486Sjhb		td->td_retval[0] = 0;
676141486Sjhb		return (0);
67743412Snewton	default:
678141486Sjhb		CHECKALTEXIST(td, uap->path, &path);
679195458Strasz		error = kern_pathconf(td, path, UIO_SYSSPACE, name, FOLLOW);
680141486Sjhb		free(path, M_TEMP);
681141486Sjhb		return (error);
68243412Snewton	}
68343412Snewton}
68443412Snewton
68543412Snewton
68643412Snewtonint
68783366Sjuliansvr4_sys_fpathconf(td, uap)
688193014Sdelphij	struct thread *td;
68943412Snewton	struct svr4_sys_fpathconf_args *uap;
69043412Snewton{
69183366Sjulian        register_t	*retval = td->td_retval;
69243412Snewton
693107849Salfred	uap->name = svr4_to_bsd_pathconf(uap->name);
69443412Snewton
695107849Salfred	switch (uap->name) {
69643412Snewton	case -1:
69743412Snewton		*retval = -1;
69843412Snewton		return EINVAL;
69943412Snewton	case 0:
70043412Snewton		*retval = 0;
70143412Snewton		return 0;
70243412Snewton	default:
703225617Skmacy		return sys_fpathconf(td, (struct fpathconf_args *)uap);
70443412Snewton	}
70543412Snewton}
706