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>
3791386Srobert#include <sys/jail.h>
3843412Snewton#include <sys/kernel.h>
39141486Sjhb#include <sys/malloc.h>
40195458Strasz#include <sys/namei.h>
4143412Snewton#include <sys/unistd.h>
4254305Snewton#include <sys/time.h>
43141486Sjhb#include <sys/syscallsubr.h>
4454305Snewton#include <sys/sysctl.h>
4554305Snewton#include <sys/sysproto.h>
46115550Sphk#include <sys/un.h>
4743412Snewton
4843412Snewton#include <vm/vm.h>
4954305Snewton
5043412Snewton#include <netinet/in.h>
5143412Snewton
5265302Sobrien#include <compat/svr4/svr4.h>
5365302Sobrien#include <compat/svr4/svr4_types.h>
5465302Sobrien#include <compat/svr4/svr4_signal.h>
5565302Sobrien#include <compat/svr4/svr4_proto.h>
5665302Sobrien#include <compat/svr4/svr4_util.h>
5765302Sobrien#include <compat/svr4/svr4_stat.h>
5865302Sobrien#include <compat/svr4/svr4_ustat.h>
5965302Sobrien#include <compat/svr4/svr4_utsname.h>
6065302Sobrien#include <compat/svr4/svr4_systeminfo.h>
6165302Sobrien#include <compat/svr4/svr4_socket.h>
6265302Sobrien#include <compat/svr4/svr4_time.h>
6343412Snewton#if defined(NOTYET)
6443412Snewton#include "svr4_fuser.h"
6543412Snewton#endif
6643412Snewton
6743412Snewton#ifdef sparc
6843412Snewton/*
6943412Snewton * Solaris-2.4 on the sparc has the old stat call using the new
7043412Snewton * stat data structure...
7143412Snewton */
7243412Snewton# define SVR4_NO_OSTAT
7343412Snewton#endif
7443412Snewton
7543412Snewtonstruct svr4_ustat_args {
7643412Snewton	svr4_dev_t		dev;
7743412Snewton	struct svr4_ustat * name;
7843412Snewton};
7943412Snewton
8092761Salfredstatic void bsd_to_svr4_xstat(struct stat *, struct svr4_xstat *);
8192761Salfredstatic void bsd_to_svr4_stat64(struct stat *, struct svr4_stat64 *);
8292761Salfredint svr4_ustat(struct thread *, struct svr4_ustat_args *);
8392761Salfredstatic int svr4_to_bsd_pathconf(int);
8443412Snewton
8543412Snewton/*
8643412Snewton * SVR4 uses named pipes as named sockets, so we tell programs
8743412Snewton * that sockets are named pipes with mode 0
8843412Snewton */
8943412Snewton#define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
9043412Snewton
9143412Snewton
9243412Snewton#ifndef SVR4_NO_OSTAT
9392761Salfredstatic void bsd_to_svr4_stat(struct stat *, struct svr4_stat *);
9443412Snewton
9543412Snewtonstatic void
9643412Snewtonbsd_to_svr4_stat(st, st4)
9743412Snewton	struct stat		*st;
9843412Snewton	struct svr4_stat 	*st4;
9943412Snewton{
10043412Snewton	memset(st4, 0, sizeof(*st4));
10143412Snewton	st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
10243412Snewton	st4->st_ino = st->st_ino;
10343412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
10443412Snewton	st4->st_nlink = st->st_nlink;
10543412Snewton	st4->st_uid = st->st_uid;
10643412Snewton	st4->st_gid = st->st_gid;
10743412Snewton	st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
10843412Snewton	st4->st_size = st->st_size;
109205792Sed	st4->st_atim = st->st_atim.tv_sec;
110205792Sed	st4->st_mtim = st->st_mtim.tv_sec;
111205792Sed	st4->st_ctim = st->st_ctim.tv_sec;
11243412Snewton}
11343412Snewton#endif
11443412Snewton
11543412Snewton
11643412Snewtonstatic void
11743412Snewtonbsd_to_svr4_xstat(st, st4)
11843412Snewton	struct stat		*st;
11943412Snewton	struct svr4_xstat	*st4;
12043412Snewton{
12143412Snewton	memset(st4, 0, sizeof(*st4));
12243412Snewton	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
12343412Snewton	st4->st_ino = st->st_ino;
12443412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
12543412Snewton	st4->st_nlink = st->st_nlink;
12643412Snewton	st4->st_uid = st->st_uid;
12743412Snewton	st4->st_gid = st->st_gid;
12843412Snewton	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
12943412Snewton	st4->st_size = st->st_size;
130205792Sed	st4->st_atim = st->st_atim;
131205792Sed	st4->st_mtim = st->st_mtim;
132205792Sed	st4->st_ctim = st->st_ctim;
13343412Snewton	st4->st_blksize = st->st_blksize;
13443412Snewton	st4->st_blocks = st->st_blocks;
13543412Snewton	strcpy(st4->st_fstype, "unknown");
13643412Snewton}
13743412Snewton
13843412Snewton
13943412Snewtonstatic void
14043412Snewtonbsd_to_svr4_stat64(st, st4)
14143412Snewton	struct stat		*st;
14243412Snewton	struct svr4_stat64	*st4;
14343412Snewton{
14443412Snewton	memset(st4, 0, sizeof(*st4));
14543412Snewton	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
14643412Snewton	st4->st_ino = st->st_ino;
14743412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
14843412Snewton	st4->st_nlink = st->st_nlink;
14943412Snewton	st4->st_uid = st->st_uid;
15043412Snewton	st4->st_gid = st->st_gid;
15143412Snewton	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
15243412Snewton	st4->st_size = st->st_size;
153205792Sed	st4->st_atim = st->st_atim;
154205792Sed	st4->st_mtim = st->st_mtim;
155205792Sed	st4->st_ctim = st->st_ctim;
15643412Snewton	st4->st_blksize = st->st_blksize;
15743412Snewton	st4->st_blocks = st->st_blocks;
15843412Snewton	strcpy(st4->st_fstype, "unknown");
15943412Snewton}
16043412Snewton
16143412Snewtonint
16283366Sjuliansvr4_sys_stat(td, uap)
16383366Sjulian	struct thread *td;
16443412Snewton	struct svr4_sys_stat_args *uap;
16543412Snewton{
166141486Sjhb	struct svr4_stat svr4_st;
167141486Sjhb	struct stat st;
168141486Sjhb	char *path;
169141486Sjhb	int error;
17043412Snewton
171141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
17243412Snewton
173141486Sjhb	error = kern_stat(td, path, UIO_SYSSPACE, &st);
174141486Sjhb	free(path, M_TEMP);
175141486Sjhb	if (error)
176141486Sjhb		return (error);
17743412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
17843412Snewton
17943412Snewton	if (S_ISSOCK(st.st_mode))
180107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
18143412Snewton
182141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
18343412Snewton}
18443412Snewton
18543412Snewton
18643412Snewtonint
18783366Sjuliansvr4_sys_lstat(td, uap)
188193014Sdelphij	struct thread *td;
18943412Snewton	struct svr4_sys_lstat_args *uap;
19043412Snewton{
191141486Sjhb	struct svr4_stat svr4_st;
192141486Sjhb	struct stat st;
193141486Sjhb	char *path;
194141486Sjhb	int error;
19543412Snewton
196141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
19743412Snewton
198141486Sjhb	error = kern_lstat(td, path, UIO_SYSSPACE, &st);
199141486Sjhb	free(path, M_TEMP);
200141486Sjhb	if (error)
201141486Sjhb		return (error);
20243412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
20343412Snewton
20443412Snewton	if (S_ISSOCK(st.st_mode))
205107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
20643412Snewton
207141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
20843412Snewton}
20943412Snewton
21043412Snewton
21143412Snewtonint
21283366Sjuliansvr4_sys_fstat(td, uap)
213193014Sdelphij	struct thread *td;
21443412Snewton	struct svr4_sys_fstat_args *uap;
21543412Snewton{
216141486Sjhb	struct svr4_stat svr4_st;
217141486Sjhb	struct stat st;
218141486Sjhb	int error;
21943412Snewton
22043412Snewton
221141486Sjhb	error = kern_fstat(td, uap->fd, &st);
222141486Sjhb	if (error)
223141486Sjhb		return (error);
22443412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
225141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
22643412Snewton}
22743412Snewton
22843412Snewton
22943412Snewtonint
23083366Sjuliansvr4_sys_xstat(td, uap)
231193014Sdelphij	struct thread *td;
23243412Snewton	struct svr4_sys_xstat_args *uap;
23343412Snewton{
234141486Sjhb	struct svr4_xstat svr4_st;
235141486Sjhb	struct stat st;
236141486Sjhb	char *path;
237141486Sjhb	int error;
23843412Snewton
239141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
24043412Snewton
241141486Sjhb	error = kern_stat(td, path, UIO_SYSSPACE, &st);
242141486Sjhb	free(path, M_TEMP);
243141486Sjhb	if (error)
244141486Sjhb		return (error);
24543412Snewton
24643412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
24743412Snewton
24843412Snewton#if defined(SOCKET_NOTYET)
24943412Snewton	if (S_ISSOCK(st.st_mode))
250107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
25143412Snewton#endif
25243412Snewton
253141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
25443412Snewton}
25543412Snewton
25643412Snewtonint
25783366Sjuliansvr4_sys_lxstat(td, uap)
258193014Sdelphij	struct thread *td;
25943412Snewton	struct svr4_sys_lxstat_args *uap;
26043412Snewton{
261141486Sjhb	struct svr4_xstat svr4_st;
262141486Sjhb	struct stat st;
263141486Sjhb	char *path;
264141486Sjhb	int error;
26543412Snewton
266141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
26743412Snewton
268141486Sjhb	error = kern_lstat(td, path, UIO_SYSSPACE, &st);
269141486Sjhb	free(path, M_TEMP);
270141486Sjhb	if (error)
271141486Sjhb		return (error);
27243412Snewton
27343412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
27443412Snewton
27543412Snewton#if defined(SOCKET_NOTYET)
27643412Snewton	if (S_ISSOCK(st.st_mode))
277107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
27843412Snewton#endif
279141486Sjhb	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
28043412Snewton}
28143412Snewton
28243412Snewton
28343412Snewtonint
28483366Sjuliansvr4_sys_fxstat(td, uap)
285193014Sdelphij	struct thread *td;
28643412Snewton	struct svr4_sys_fxstat_args *uap;
28743412Snewton{
288141486Sjhb	struct svr4_xstat svr4_st;
289141486Sjhb	struct stat st;
290141486Sjhb	int error;
29143412Snewton
29243412Snewton
293141486Sjhb	error = kern_fstat(td, uap->fd, &st);
294141486Sjhb	if (error)
295141486Sjhb		return (error);
29643412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
297141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
29843412Snewton}
29943412Snewton
30043412Snewtonint
30183366Sjuliansvr4_sys_stat64(td, uap)
302193014Sdelphij	struct thread *td;
30343412Snewton	struct svr4_sys_stat64_args *uap;
30443412Snewton{
305141486Sjhb	struct svr4_stat64 svr4_st;
306141486Sjhb	struct stat st;
307141486Sjhb	char *path;
308141486Sjhb	int error;
30943412Snewton
310141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
31143412Snewton
312141486Sjhb	error = kern_stat(td, path, UIO_SYSSPACE, &st);
313141486Sjhb	free(path, M_TEMP);
314141486Sjhb	if (error)
315141486Sjhb		return (error);
31643412Snewton
31743412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
31843412Snewton
31943412Snewton	if (S_ISSOCK(st.st_mode))
320107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
32143412Snewton
322141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
32343412Snewton}
32443412Snewton
32543412Snewton
32643412Snewtonint
32783366Sjuliansvr4_sys_lstat64(td, uap)
328193014Sdelphij	struct thread *td;
32943412Snewton	struct svr4_sys_lstat64_args *uap;
33043412Snewton{
331141486Sjhb	struct svr4_stat64 svr4_st;
332141486Sjhb	struct stat st;
333141486Sjhb	char *path;
334141486Sjhb	int error;
33543412Snewton
336141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
33743412Snewton
338141486Sjhb	error = kern_lstat(td, path, UIO_SYSSPACE, &st);
339141486Sjhb	free(path, M_TEMP);
340141486Sjhb	if (error)
341141486Sjhb		return (error);
34243412Snewton
34343412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
34443412Snewton
34543412Snewton	if (S_ISSOCK(st.st_mode))
346107849Salfred		(void) svr4_add_socket(td, uap->path, &st);
34743412Snewton
348141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
34943412Snewton}
35043412Snewton
35143412Snewton
35243412Snewtonint
35383366Sjuliansvr4_sys_fstat64(td, uap)
354193014Sdelphij	struct thread *td;
35543412Snewton	struct svr4_sys_fstat64_args *uap;
35643412Snewton{
357141486Sjhb	struct svr4_stat64 svr4_st;
358141486Sjhb	struct stat st;
359141486Sjhb	int error;
36043412Snewton
361141486Sjhb	error = kern_fstat(td, uap->fd, &st);
362141486Sjhb	if (error)
363141486Sjhb		return (error);
36443412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
365141486Sjhb	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
36643412Snewton}
36743412Snewton
36843412Snewton
36943412Snewtonint
37083366Sjuliansvr4_ustat(td, uap)
371193014Sdelphij	struct thread *td;
37243412Snewton	struct svr4_ustat_args *uap;
37343412Snewton{
37443412Snewton	struct svr4_ustat	us;
37543412Snewton	int			error;
37643412Snewton
37743412Snewton	memset(&us, 0, sizeof us);
37843412Snewton
37943412Snewton	/*
38043412Snewton         * XXX: should set f_tfree and f_tinode at least
38143412Snewton         * How do we translate dev -> fstat? (and then to svr4_ustat)
38243412Snewton         */
383107849Salfred	if ((error = copyout(&us, uap->name, sizeof us)) != 0)
38443412Snewton		return (error);
38543412Snewton
38643412Snewton	return 0;
38743412Snewton}
38843412Snewton
389193066Sjamie/*extern char ostype[], osrelease[], version[], machine[];*/
39043412Snewton
39143412Snewtonint
39283366Sjuliansvr4_sys_uname(td, uap)
393193014Sdelphij	struct thread *td;
39443412Snewton	struct svr4_sys_uname_args *uap;
39543412Snewton{
39643412Snewton	struct svr4_utsname	sut;
39743412Snewton
39843412Snewton	memset(&sut, 0, sizeof(sut));
39943412Snewton
400105360Srobert	strlcpy(sut.sysname, ostype, sizeof(sut.sysname));
40191392Srobert	getcredhostname(td->td_ucred, sut.nodename, sizeof(sut.nodename));
402105360Srobert	strlcpy(sut.release, osrelease, sizeof(sut.release));
403105360Srobert	strlcpy(sut.version, version, sizeof(sut.version));
404105360Srobert	strlcpy(sut.machine, machine, sizeof(sut.machine));
40543412Snewton
406107849Salfred	return copyout((caddr_t) &sut, (caddr_t) uap->name,
40743412Snewton		       sizeof(struct svr4_utsname));
40843412Snewton}
40943412Snewton
41043412Snewtonint
41183366Sjuliansvr4_sys_systeminfo(td, uap)
41283366Sjulian	struct thread *td;
41343412Snewton	struct svr4_sys_systeminfo_args *uap;
41443412Snewton{
41549264Snewton	char		*str = NULL;
41649264Snewton	int		error = 0;
41783366Sjulian	register_t	*retval = td->td_retval;
418194090Sjamie	u_long		hostid;
41949264Snewton	size_t		len = 0;
420193066Sjamie	char		buf[MAXHOSTNAMELEN];
421107849Salfred	u_int		rlen = uap->len;
42243412Snewton
423107849Salfred	switch (uap->what) {
42443412Snewton	case SVR4_SI_SYSNAME:
42543412Snewton		str = ostype;
42643412Snewton		break;
42743412Snewton
42843412Snewton	case SVR4_SI_HOSTNAME:
429193066Sjamie		getcredhostname(td->td_ucred, buf, sizeof(buf));
430193066Sjamie		str = buf;
43143412Snewton		break;
43243412Snewton
43343412Snewton	case SVR4_SI_RELEASE:
43443412Snewton		str = osrelease;
43543412Snewton		break;
43643412Snewton
43743412Snewton	case SVR4_SI_VERSION:
43843412Snewton		str = version;
43943412Snewton		break;
44043412Snewton
44143412Snewton	case SVR4_SI_MACHINE:
44243412Snewton		str = machine;
44343412Snewton		break;
44443412Snewton
44543412Snewton	case SVR4_SI_ARCHITECTURE:
44643412Snewton		str = machine;
44743412Snewton		break;
44843412Snewton
449193017Sdelphij	case SVR4_SI_ISALIST:
450193017Sdelphij#if defined(__sparc__)
451193017Sdelphij		str = "sparcv9 sparcv9-fsmuld sparcv8 sparcv8-fsmuld sparcv7 sparc";
452193017Sdelphij#elif defined(__i386__)
453193017Sdelphij		str = "i386";
454193017Sdelphij#elif defined(__amd64__)
455193017Sdelphij		str = "amd64";
456193017Sdelphij#else
457193017Sdelphij		str = "unknown";
458193017Sdelphij#endif
459193017Sdelphij		break;
460193017Sdelphij
46143412Snewton	case SVR4_SI_HW_SERIAL:
462194090Sjamie		getcredhostid(td->td_ucred, &hostid);
463194090Sjamie		snprintf(buf, sizeof(buf), "%lu", hostid);
464193016Sdelphij		str = buf;
46543412Snewton		break;
46643412Snewton
46743412Snewton	case SVR4_SI_HW_PROVIDER:
46843412Snewton		str = ostype;
46943412Snewton		break;
47043412Snewton
47143412Snewton	case SVR4_SI_SRPC_DOMAIN:
472194090Sjamie		getcreddomainname(td->td_ucred, buf, sizeof(buf));
473193066Sjamie		str = buf;
47443412Snewton		break;
47543412Snewton
47643412Snewton	case SVR4_SI_PLATFORM:
477193017Sdelphij#if defined(__i386__)
47843412Snewton		str = "i86pc";
47943412Snewton#else
48043412Snewton		str = "unknown";
48143412Snewton#endif
48243412Snewton		break;
48343412Snewton
48443412Snewton	case SVR4_SI_KERB_REALM:
48543412Snewton		str = "unsupported";
48643412Snewton		break;
48743412Snewton#if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
48843412Snewton	case SVR4_SI_SET_HOSTNAME:
48943412Snewton		name = KERN_HOSTNAME;
490107849Salfred		return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
49143412Snewton
49243412Snewton	case SVR4_SI_SET_SRPC_DOMAIN:
49343412Snewton		name = KERN_NISDOMAINNAME;
494107849Salfred		return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
49543412Snewton#else
49643412Snewton	case SVR4_SI_SET_HOSTNAME:
49743412Snewton        case SVR4_SI_SET_SRPC_DOMAIN:
49843412Snewton		/* FALLTHROUGH */
49943412Snewton#endif
50043412Snewton	case SVR4_SI_SET_KERB_REALM:
50143412Snewton		return 0;
50243412Snewton
50343412Snewton	default:
504107849Salfred		DPRINTF(("Bad systeminfo command %d\n", uap->what));
50543412Snewton		return ENOSYS;
50643412Snewton	}
50743412Snewton
50843412Snewton	if (str) {
50943412Snewton		len = strlen(str) + 1;
51043412Snewton		if (len > rlen)
51143412Snewton			len = rlen;
51243412Snewton
513107849Salfred		if (uap->buf) {
514107849Salfred			error = copyout(str, uap->buf, len);
51543412Snewton			if (error)
51643412Snewton				return error;
51743412Snewton			/* make sure we are NULL terminated */
51843412Snewton			buf[0] = '\0';
519107849Salfred			error = copyout(buf, &(uap->buf[len - 1]), 1);
52043412Snewton		}
52143412Snewton		else
52243412Snewton			error = 0;
52343412Snewton	}
52443412Snewton	/* XXX NetBSD has hostname setting stuff here.  Why would an emulator
52543412Snewton	   want to do that? */
52643412Snewton
52743412Snewton	*retval = len;
52843412Snewton	return error;
52943412Snewton}
53043412Snewton
53143412Snewtonint
53283366Sjuliansvr4_sys_utssys(td, uap)
533193014Sdelphij	struct thread *td;
53443412Snewton	struct svr4_sys_utssys_args *uap;
53543412Snewton{
536107849Salfred	switch (uap->sel) {
53743412Snewton	case 0:		/* uname(2)  */
53843412Snewton		{
53943412Snewton			struct svr4_sys_uname_args ua;
540107849Salfred			ua.name = uap->a1;
54183366Sjulian			return svr4_sys_uname(td, &ua);
54243412Snewton		}
54343412Snewton
54443412Snewton	case 2:		/* ustat(2)  */
54543412Snewton		{
54643412Snewton			struct svr4_ustat_args ua;
547107849Salfred			ua.dev = (svr4_dev_t) uap->a2;
548107849Salfred			ua.name = uap->a1;
54983366Sjulian			return svr4_ustat(td, &ua);
55043412Snewton		}
55143412Snewton
55243412Snewton	case 3:		/* fusers(2) */
55343412Snewton		return ENOSYS;
55443412Snewton
55543412Snewton	default:
55643412Snewton		return ENOSYS;
55743412Snewton	}
55843412Snewton	return ENOSYS;
55943412Snewton}
56043412Snewton
56143412Snewton
56243412Snewtonint
56383366Sjuliansvr4_sys_utime(td, uap)
564193014Sdelphij	struct thread *td;
56543412Snewton	struct svr4_sys_utime_args *uap;
56643412Snewton{
56743412Snewton	struct svr4_utimbuf ub;
568141486Sjhb	struct timeval tbuf[2], *tp;
569141486Sjhb	char *path;
57043412Snewton	int error;
571141486Sjhb
572107849Salfred	if (uap->ubuf != NULL) {
573141486Sjhb		error = copyin(uap->ubuf, &ub, sizeof(ub));
574141486Sjhb		if (error)
575141486Sjhb			return (error);
57643412Snewton		tbuf[0].tv_sec = ub.actime;
57743412Snewton		tbuf[0].tv_usec = 0;
57843412Snewton		tbuf[1].tv_sec = ub.modtime;
57943412Snewton		tbuf[1].tv_usec = 0;
580141486Sjhb		tp = tbuf;
581141486Sjhb	} else
582141486Sjhb		tp = NULL;
583141486Sjhb
584141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
585141486Sjhb	error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE);
586141486Sjhb	free(path, M_TEMP);
587141486Sjhb	return (error);
58843412Snewton}
58943412Snewton
59043412Snewton
59143412Snewtonint
59283366Sjuliansvr4_sys_utimes(td, uap)
593193014Sdelphij	struct thread *td;
59443412Snewton	struct svr4_sys_utimes_args *uap;
59543412Snewton{
596141486Sjhb	char *path;
597141486Sjhb	int error;
598141486Sjhb
599141486Sjhb	CHECKALTEXIST(td, uap->path, &path);
600141486Sjhb	error = kern_utimes(td, path, UIO_SYSSPACE, uap->tptr, UIO_USERSPACE);
601141486Sjhb	free(path, M_TEMP);
602141486Sjhb	return (error);
60343412Snewton}
60443412Snewton
60543412Snewtonstatic int
60643412Snewtonsvr4_to_bsd_pathconf(name)
60743412Snewton	int name;
60843412Snewton{
60943412Snewton	switch (name) {
61043412Snewton	case SVR4_PC_LINK_MAX:
61143412Snewton	    	return _PC_LINK_MAX;
61243412Snewton
61343412Snewton	case SVR4_PC_MAX_CANON:
61443412Snewton		return _PC_MAX_CANON;
61543412Snewton
61643412Snewton	case SVR4_PC_MAX_INPUT:
61743412Snewton		return _PC_MAX_INPUT;
61843412Snewton
61943412Snewton	case SVR4_PC_NAME_MAX:
62043412Snewton		return _PC_NAME_MAX;
62143412Snewton
62243412Snewton	case SVR4_PC_PATH_MAX:
62343412Snewton		return _PC_PATH_MAX;
62443412Snewton
62543412Snewton	case SVR4_PC_PIPE_BUF:
62643412Snewton		return _PC_PIPE_BUF;
62743412Snewton
62843412Snewton	case SVR4_PC_NO_TRUNC:
62943412Snewton		return _PC_NO_TRUNC;
63043412Snewton
63143412Snewton	case SVR4_PC_VDISABLE:
63243412Snewton		return _PC_VDISABLE;
63343412Snewton
63443412Snewton	case SVR4_PC_CHOWN_RESTRICTED:
63543412Snewton		return _PC_CHOWN_RESTRICTED;
63643412Snewton	case SVR4_PC_SYNC_IO:
63743412Snewton#if defined(_PC_SYNC_IO)
63843412Snewton		return _PC_SYNC_IO;
63943412Snewton#else
64043412Snewton		return 0;
64143412Snewton#endif
64243412Snewton	case SVR4_PC_ASYNC_IO:
64343412Snewton	case SVR4_PC_PRIO_IO:
64443412Snewton		/* Not supported */
64543412Snewton		return 0;
64643412Snewton
64743412Snewton	default:
64843412Snewton		/* Invalid */
64943412Snewton		return -1;
65043412Snewton	}
65143412Snewton}
65243412Snewton
65343412Snewton
65443412Snewtonint
65583366Sjuliansvr4_sys_pathconf(td, uap)
656193014Sdelphij	struct thread *td;
65743412Snewton	struct svr4_sys_pathconf_args *uap;
65843412Snewton{
659141486Sjhb	char *path;
660141486Sjhb	int error, name;
66143412Snewton
662141486Sjhb	name = svr4_to_bsd_pathconf(uap->name);
66343412Snewton
664141486Sjhb	switch (name) {
66543412Snewton	case -1:
666141486Sjhb		td->td_retval[0] = -1;
667141486Sjhb		return (EINVAL);
66843412Snewton	case 0:
669141486Sjhb		td->td_retval[0] = 0;
670141486Sjhb		return (0);
67143412Snewton	default:
672141486Sjhb		CHECKALTEXIST(td, uap->path, &path);
673195458Strasz		error = kern_pathconf(td, path, UIO_SYSSPACE, name, FOLLOW);
674141486Sjhb		free(path, M_TEMP);
675141486Sjhb		return (error);
67643412Snewton	}
67743412Snewton}
67843412Snewton
67943412Snewton
68043412Snewtonint
68183366Sjuliansvr4_sys_fpathconf(td, uap)
682193014Sdelphij	struct thread *td;
68343412Snewton	struct svr4_sys_fpathconf_args *uap;
68443412Snewton{
68583366Sjulian        register_t	*retval = td->td_retval;
68643412Snewton
687107849Salfred	uap->name = svr4_to_bsd_pathconf(uap->name);
68843412Snewton
689107849Salfred	switch (uap->name) {
69043412Snewton	case -1:
69143412Snewton		*retval = -1;
69243412Snewton		return EINVAL;
69343412Snewton	case 0:
69443412Snewton		*retval = 0;
69543412Snewton		return 0;
69643412Snewton	default:
697225617Skmacy		return sys_fpathconf(td, (struct fpathconf_args *)uap);
69843412Snewton	}
69943412Snewton}
700