svr4_stat.c revision 83366
143412Snewton/*
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.
2749264Snewton *
2850477Speter * $FreeBSD: head/sys/compat/svr4/svr4_stat.c 83366 2001-09-12 08:38:13Z julian $
2943412Snewton */
3043412Snewton
3143412Snewton#include <sys/param.h>
3243412Snewton#include <sys/systm.h>
3343412Snewton#include <sys/proc.h>
3443412Snewton#include <sys/stat.h>
3543412Snewton#include <sys/filedesc.h>
3643412Snewton#include <sys/kernel.h>
3743412Snewton#include <sys/unistd.h>
3854305Snewton#include <sys/time.h>
3954305Snewton#include <sys/sysctl.h>
4054305Snewton#include <sys/sysproto.h>
4143412Snewton
4243412Snewton#include <vm/vm.h>
4354305Snewton
4443412Snewton#include <netinet/in.h>
4543412Snewton
4665302Sobrien#include <compat/svr4/svr4.h>
4765302Sobrien#include <compat/svr4/svr4_types.h>
4865302Sobrien#include <compat/svr4/svr4_signal.h>
4965302Sobrien#include <compat/svr4/svr4_proto.h>
5065302Sobrien#include <compat/svr4/svr4_util.h>
5165302Sobrien#include <compat/svr4/svr4_stat.h>
5265302Sobrien#include <compat/svr4/svr4_ustat.h>
5365302Sobrien#include <compat/svr4/svr4_utsname.h>
5465302Sobrien#include <compat/svr4/svr4_systeminfo.h>
5565302Sobrien#include <compat/svr4/svr4_socket.h>
5665302Sobrien#include <compat/svr4/svr4_time.h>
5743412Snewton#if defined(NOTYET)
5843412Snewton#include "svr4_fuser.h"
5943412Snewton#endif
6043412Snewton
6143412Snewton#ifdef sparc
6243412Snewton/*
6343412Snewton * Solaris-2.4 on the sparc has the old stat call using the new
6443412Snewton * stat data structure...
6543412Snewton */
6643412Snewton# define SVR4_NO_OSTAT
6743412Snewton#endif
6843412Snewton
6943412Snewtonstruct svr4_ustat_args {
7043412Snewton	svr4_dev_t		dev;
7143412Snewton	struct svr4_ustat * name;
7243412Snewton};
7343412Snewton
7443412Snewtonstatic void bsd_to_svr4_xstat __P((struct stat *, struct svr4_xstat *));
7543412Snewtonstatic void bsd_to_svr4_stat64 __P((struct stat *, struct svr4_stat64 *));
7683366Sjulianint svr4_ustat __P((struct thread *, struct svr4_ustat_args *));
7743412Snewtonstatic int svr4_to_bsd_pathconf __P((int));
7843412Snewton
7943412Snewton/*
8043412Snewton * SVR4 uses named pipes as named sockets, so we tell programs
8143412Snewton * that sockets are named pipes with mode 0
8243412Snewton */
8343412Snewton#define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
8443412Snewton
8543412Snewton
8643412Snewton#ifndef SVR4_NO_OSTAT
8743412Snewtonstatic void bsd_to_svr4_stat __P((struct stat *, struct svr4_stat *));
8843412Snewton
8943412Snewtonstatic void
9043412Snewtonbsd_to_svr4_stat(st, st4)
9143412Snewton	struct stat		*st;
9243412Snewton	struct svr4_stat 	*st4;
9343412Snewton{
9443412Snewton	memset(st4, 0, sizeof(*st4));
9543412Snewton	st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
9643412Snewton	st4->st_ino = st->st_ino;
9743412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
9843412Snewton	st4->st_nlink = st->st_nlink;
9943412Snewton	st4->st_uid = st->st_uid;
10043412Snewton	st4->st_gid = st->st_gid;
10143412Snewton	st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
10243412Snewton	st4->st_size = st->st_size;
10343412Snewton	st4->st_atim = st->st_atimespec.tv_sec;
10443412Snewton	st4->st_mtim = st->st_mtimespec.tv_sec;
10543412Snewton	st4->st_ctim = st->st_ctimespec.tv_sec;
10643412Snewton}
10743412Snewton#endif
10843412Snewton
10943412Snewton
11043412Snewtonstatic void
11143412Snewtonbsd_to_svr4_xstat(st, st4)
11243412Snewton	struct stat		*st;
11343412Snewton	struct svr4_xstat	*st4;
11443412Snewton{
11543412Snewton	memset(st4, 0, sizeof(*st4));
11643412Snewton	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
11743412Snewton	st4->st_ino = st->st_ino;
11843412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
11943412Snewton	st4->st_nlink = st->st_nlink;
12043412Snewton	st4->st_uid = st->st_uid;
12143412Snewton	st4->st_gid = st->st_gid;
12243412Snewton	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
12343412Snewton	st4->st_size = st->st_size;
12443412Snewton	st4->st_atim = st->st_atimespec;
12543412Snewton	st4->st_mtim = st->st_mtimespec;
12643412Snewton	st4->st_ctim = st->st_ctimespec;
12743412Snewton	st4->st_blksize = st->st_blksize;
12843412Snewton	st4->st_blocks = st->st_blocks;
12943412Snewton	strcpy(st4->st_fstype, "unknown");
13043412Snewton}
13143412Snewton
13243412Snewton
13343412Snewtonstatic void
13443412Snewtonbsd_to_svr4_stat64(st, st4)
13543412Snewton	struct stat		*st;
13643412Snewton	struct svr4_stat64	*st4;
13743412Snewton{
13843412Snewton	memset(st4, 0, sizeof(*st4));
13943412Snewton	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
14043412Snewton	st4->st_ino = st->st_ino;
14143412Snewton	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
14243412Snewton	st4->st_nlink = st->st_nlink;
14343412Snewton	st4->st_uid = st->st_uid;
14443412Snewton	st4->st_gid = st->st_gid;
14543412Snewton	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
14643412Snewton	st4->st_size = st->st_size;
14743412Snewton	st4->st_atim = st->st_atimespec;
14843412Snewton	st4->st_mtim = st->st_mtimespec;
14943412Snewton	st4->st_ctim = st->st_ctimespec;
15043412Snewton	st4->st_blksize = st->st_blksize;
15143412Snewton	st4->st_blocks = st->st_blocks;
15243412Snewton	strcpy(st4->st_fstype, "unknown");
15343412Snewton}
15443412Snewton
15543412Snewtonint
15683366Sjuliansvr4_sys_stat(td, uap)
15783366Sjulian	struct thread *td;
15843412Snewton	struct svr4_sys_stat_args *uap;
15943412Snewton{
16043412Snewton	struct stat		st;
16143412Snewton	struct svr4_stat	svr4_st;
16243412Snewton	struct stat_args	cup;
16343412Snewton	int			error;
16443412Snewton	caddr_t sg = stackgap_init();
16543412Snewton
16683366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
16743412Snewton
16843412Snewton	SCARG(&cup, path) = SCARG(uap, path);
16943412Snewton	SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
17043412Snewton
17143412Snewton
17283366Sjulian	if ((error = stat(td, &cup)) != 0)
17343412Snewton		return error;
17443412Snewton
17543412Snewton	if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
17643412Snewton		return error;
17743412Snewton
17843412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
17943412Snewton
18043412Snewton	if (S_ISSOCK(st.st_mode))
18183366Sjulian		(void) svr4_add_socket(td, SCARG(uap, path), &st);
18243412Snewton
18343412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
18443412Snewton		return error;
18543412Snewton
18643412Snewton	return 0;
18743412Snewton}
18843412Snewton
18943412Snewton
19043412Snewtonint
19183366Sjuliansvr4_sys_lstat(td, uap)
19283366Sjulian	register struct thread *td;
19343412Snewton	struct svr4_sys_lstat_args *uap;
19443412Snewton{
19543412Snewton	struct stat		st;
19643412Snewton	struct svr4_stat	svr4_st;
19743412Snewton	struct lstat_args	cup;
19843412Snewton	int			error;
19949264Snewton	caddr_t			sg = stackgap_init();
20043412Snewton
20183366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
20243412Snewton
20343412Snewton	SCARG(&cup, path) = SCARG(uap, path);
20443412Snewton	SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
20543412Snewton
20683366Sjulian	if ((error = lstat(td, &cup)) != 0)
20743412Snewton		return error;
20843412Snewton
20943412Snewton	if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
21043412Snewton		return error;
21143412Snewton
21243412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
21343412Snewton
21443412Snewton	if (S_ISSOCK(st.st_mode))
21583366Sjulian		(void) svr4_add_socket(td, SCARG(uap, path), &st);
21643412Snewton
21743412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
21843412Snewton		return error;
21943412Snewton
22043412Snewton	return 0;
22143412Snewton}
22243412Snewton
22343412Snewton
22443412Snewtonint
22583366Sjuliansvr4_sys_fstat(td, uap)
22683366Sjulian	register struct thread *td;
22743412Snewton	struct svr4_sys_fstat_args *uap;
22843412Snewton{
22943412Snewton	struct stat		st;
23043412Snewton	struct svr4_stat	svr4_st;
23143412Snewton	struct fstat_args	cup;
23249264Snewton	int			error;
23349264Snewton	caddr_t			sg = stackgap_init();
23443412Snewton
23543412Snewton	SCARG(&cup, fd) = SCARG(uap, fd);
23643412Snewton	SCARG(&cup, sb) = stackgap_alloc(&sg, sizeof(struct stat));
23743412Snewton
23883366Sjulian	if ((error = fstat(td, &cup)) != 0)
23943412Snewton		return error;
24043412Snewton
24143412Snewton	if ((error = copyin(SCARG(&cup, sb), &st, sizeof st)) != 0)
24243412Snewton		return error;
24343412Snewton
24443412Snewton	bsd_to_svr4_stat(&st, &svr4_st);
24543412Snewton
24643412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
24743412Snewton		return error;
24843412Snewton
24943412Snewton	return 0;
25043412Snewton}
25143412Snewton
25243412Snewton
25343412Snewtonint
25483366Sjuliansvr4_sys_xstat(td, uap)
25583366Sjulian	register struct thread *td;
25643412Snewton	struct svr4_sys_xstat_args *uap;
25743412Snewton{
25843412Snewton	struct stat		st;
25943412Snewton	struct svr4_xstat	svr4_st;
26043412Snewton	struct stat_args	cup;
26149264Snewton	int			error;
26243412Snewton
26343412Snewton	caddr_t sg = stackgap_init();
26483366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
26543412Snewton
26643412Snewton	SCARG(&cup, path) = SCARG(uap, path);
26743412Snewton	SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
26843412Snewton
26983366Sjulian	if ((error = stat(td, &cup)) != 0)
27043412Snewton		return error;
27143412Snewton
27243412Snewton	if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
27343412Snewton		return error;
27443412Snewton
27543412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
27643412Snewton
27743412Snewton#if defined(SOCKET_NOTYET)
27843412Snewton	if (S_ISSOCK(st.st_mode))
27983366Sjulian		(void) svr4_add_socket(td, SCARG(uap, path), &st);
28043412Snewton#endif
28143412Snewton
28243412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
28343412Snewton		return error;
28443412Snewton
28543412Snewton	return 0;
28643412Snewton}
28743412Snewton
28843412Snewtonint
28983366Sjuliansvr4_sys_lxstat(td, uap)
29083366Sjulian	register struct thread *td;
29143412Snewton	struct svr4_sys_lxstat_args *uap;
29243412Snewton{
29343412Snewton	struct stat		st;
29443412Snewton	struct svr4_xstat	svr4_st;
29543412Snewton	struct lstat_args	cup;
29643412Snewton	int			error;
29743412Snewton	caddr_t sg = stackgap_init();
29883366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
29943412Snewton
30043412Snewton	SCARG(&cup, path) = SCARG(uap, path);
30143412Snewton	SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
30243412Snewton
30383366Sjulian	if ((error = lstat(td, &cup)) != 0)
30443412Snewton		return error;
30543412Snewton
30643412Snewton	if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
30743412Snewton		return error;
30843412Snewton
30943412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
31043412Snewton
31143412Snewton#if defined(SOCKET_NOTYET)
31243412Snewton	if (S_ISSOCK(st.st_mode))
31383366Sjulian		(void) svr4_add_socket(td, SCARG(uap, path), &st);
31443412Snewton#endif
31543412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
31643412Snewton		return error;
31743412Snewton
31843412Snewton	return 0;
31943412Snewton}
32043412Snewton
32143412Snewton
32243412Snewtonint
32383366Sjuliansvr4_sys_fxstat(td, uap)
32483366Sjulian	register struct thread *td;
32543412Snewton	struct svr4_sys_fxstat_args *uap;
32643412Snewton{
32743412Snewton	struct stat		st;
32843412Snewton	struct svr4_xstat	svr4_st;
32943412Snewton	struct fstat_args	cup;
33043412Snewton	int			error;
33143412Snewton
33243412Snewton	caddr_t sg = stackgap_init();
33343412Snewton
33443412Snewton	SCARG(&cup, fd) = SCARG(uap, fd);
33543412Snewton	SCARG(&cup, sb) = stackgap_alloc(&sg, sizeof(struct stat));
33643412Snewton
33783366Sjulian	if ((error = fstat(td, &cup)) != 0)
33843412Snewton		return error;
33943412Snewton
34043412Snewton	if ((error = copyin(SCARG(&cup, sb), &st, sizeof st)) != 0)
34143412Snewton		return error;
34243412Snewton
34343412Snewton	bsd_to_svr4_xstat(&st, &svr4_st);
34443412Snewton
34543412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
34643412Snewton		return error;
34743412Snewton
34843412Snewton	return 0;
34943412Snewton}
35043412Snewton
35143412Snewtonint
35283366Sjuliansvr4_sys_stat64(td, uap)
35383366Sjulian	register struct thread *td;
35443412Snewton	struct svr4_sys_stat64_args *uap;
35543412Snewton{
35643412Snewton	struct stat		st;
35743412Snewton	struct svr4_stat64	svr4_st;
35843412Snewton	struct stat_args	cup;
35949264Snewton	int			error;
36049264Snewton	caddr_t			sg = stackgap_init();
36143412Snewton
36283366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
36343412Snewton
36443412Snewton	SCARG(&cup, path) = SCARG(uap, path);
36543412Snewton	SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
36643412Snewton
36783366Sjulian	if ((error = stat(td, &cup)) != 0)
36843412Snewton		return error;
36943412Snewton
37043412Snewton	if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
37143412Snewton		return error;
37243412Snewton
37343412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
37443412Snewton
37543412Snewton	if (S_ISSOCK(st.st_mode))
37683366Sjulian		(void) svr4_add_socket(td, SCARG(uap, path), &st);
37743412Snewton
37843412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
37943412Snewton		return error;
38043412Snewton
38143412Snewton	return 0;
38243412Snewton}
38343412Snewton
38443412Snewton
38543412Snewtonint
38683366Sjuliansvr4_sys_lstat64(td, uap)
38783366Sjulian	register struct thread *td;
38843412Snewton	struct svr4_sys_lstat64_args *uap;
38943412Snewton{
39043412Snewton	struct stat		st;
39143412Snewton	struct svr4_stat64	svr4_st;
39243412Snewton	struct stat_args	cup;
39349264Snewton	int			error;
39449264Snewton	caddr_t			sg = stackgap_init();
39543412Snewton
39683366Sjulian	CHECKALTEXIST(td, &sg, (char *) SCARG(uap, path));
39743412Snewton
39843412Snewton	SCARG(&cup, path) = SCARG(uap, path);
39943412Snewton	SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
40043412Snewton
40183366Sjulian	if ((error = lstat(td, (struct lstat_args *)&cup)) != 0)
40243412Snewton		return error;
40343412Snewton
40443412Snewton	if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
40543412Snewton		return error;
40643412Snewton
40743412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
40843412Snewton
40943412Snewton	if (S_ISSOCK(st.st_mode))
41083366Sjulian		(void) svr4_add_socket(td, SCARG(uap, path), &st);
41143412Snewton
41243412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
41343412Snewton		return error;
41443412Snewton
41543412Snewton	return 0;
41643412Snewton}
41743412Snewton
41843412Snewton
41943412Snewtonint
42083366Sjuliansvr4_sys_fstat64(td, uap)
42183366Sjulian	register struct thread *td;
42243412Snewton	struct svr4_sys_fstat64_args *uap;
42343412Snewton{
42443412Snewton	struct stat		st;
42543412Snewton	struct svr4_stat64	svr4_st;
42643412Snewton	struct fstat_args	cup;
42749264Snewton	int			error;
42843412Snewton	caddr_t sg = stackgap_init();
42943412Snewton
43043412Snewton	SCARG(&cup, fd) = SCARG(uap, fd);
43143412Snewton	SCARG(&cup, sb) = stackgap_alloc(&sg, sizeof(struct stat));
43243412Snewton
43383366Sjulian	if ((error = fstat(td, &cup)) != 0)
43443412Snewton		return error;
43543412Snewton
43643412Snewton	if ((error = copyin(SCARG(&cup, sb), &st, sizeof st)) != 0)
43743412Snewton		return error;
43843412Snewton
43943412Snewton	bsd_to_svr4_stat64(&st, &svr4_st);
44043412Snewton
44143412Snewton	if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
44243412Snewton		return error;
44343412Snewton
44443412Snewton	return 0;
44543412Snewton}
44643412Snewton
44743412Snewton
44843412Snewtonint
44983366Sjuliansvr4_ustat(td, uap)
45083366Sjulian	register struct thread *td;
45143412Snewton	struct svr4_ustat_args *uap;
45243412Snewton{
45343412Snewton	struct svr4_ustat	us;
45443412Snewton	int			error;
45543412Snewton
45643412Snewton	memset(&us, 0, sizeof us);
45743412Snewton
45843412Snewton	/*
45943412Snewton         * XXX: should set f_tfree and f_tinode at least
46043412Snewton         * How do we translate dev -> fstat? (and then to svr4_ustat)
46143412Snewton         */
46243412Snewton	if ((error = copyout(&us, SCARG(uap, name), sizeof us)) != 0)
46343412Snewton		return (error);
46443412Snewton
46543412Snewton	return 0;
46643412Snewton}
46743412Snewton
46843412Snewton/*extern char ostype[], hostname[], osrelease[], version[], machine[];*/
46943412Snewton
47043412Snewtonint
47183366Sjuliansvr4_sys_uname(td, uap)
47283366Sjulian	register struct thread *td;
47343412Snewton	struct svr4_sys_uname_args *uap;
47443412Snewton{
47543412Snewton	struct svr4_utsname	sut;
47643412Snewton
47743412Snewton
47843412Snewton	memset(&sut, 0, sizeof(sut));
47943412Snewton
48043412Snewton	strncpy(sut.sysname, ostype, sizeof(sut.sysname));
48143412Snewton	sut.sysname[sizeof(sut.sysname) - 1] = '\0';
48243412Snewton
48343412Snewton	strncpy(sut.nodename, hostname, sizeof(sut.nodename));
48443412Snewton	sut.nodename[sizeof(sut.nodename) - 1] = '\0';
48543412Snewton
48643412Snewton	strncpy(sut.release, osrelease, sizeof(sut.release));
48743412Snewton	sut.release[sizeof(sut.release) - 1] = '\0';
48843412Snewton
48943412Snewton	strncpy(sut.version, version, sizeof(sut.version));
49043412Snewton	sut.version[sizeof(sut.version) - 1] = '\0';
49143412Snewton
49243412Snewton	strncpy(sut.machine, machine, sizeof(sut.machine));
49343412Snewton	sut.machine[sizeof(sut.machine) - 1] = '\0';
49443412Snewton
49543412Snewton	return copyout((caddr_t) &sut, (caddr_t) SCARG(uap, name),
49643412Snewton		       sizeof(struct svr4_utsname));
49743412Snewton}
49843412Snewton
49943412Snewtonint
50083366Sjuliansvr4_sys_systeminfo(td, uap)
50183366Sjulian	struct thread *td;
50243412Snewton	struct svr4_sys_systeminfo_args *uap;
50343412Snewton{
50449264Snewton	char		*str = NULL;
50549264Snewton	int		error = 0;
50683366Sjulian	register_t	*retval = td->td_retval;
50749264Snewton	size_t		len = 0;
50849264Snewton	char		buf[1];   /* XXX NetBSD uses 256, but that seems
50949264Snewton				     like awfully excessive kstack usage
51049264Snewton				     for an empty string... */
51149264Snewton	u_int		rlen = SCARG(uap, len);
51243412Snewton
51343412Snewton	switch (SCARG(uap, what)) {
51443412Snewton	case SVR4_SI_SYSNAME:
51543412Snewton		str = ostype;
51643412Snewton		break;
51743412Snewton
51843412Snewton	case SVR4_SI_HOSTNAME:
51943412Snewton		str = hostname;
52043412Snewton		break;
52143412Snewton
52243412Snewton	case SVR4_SI_RELEASE:
52343412Snewton		str = osrelease;
52443412Snewton		break;
52543412Snewton
52643412Snewton	case SVR4_SI_VERSION:
52743412Snewton		str = version;
52843412Snewton		break;
52943412Snewton
53043412Snewton	case SVR4_SI_MACHINE:
53143412Snewton		str = machine;
53243412Snewton		break;
53343412Snewton
53443412Snewton	case SVR4_SI_ARCHITECTURE:
53543412Snewton		str = machine;
53643412Snewton		break;
53743412Snewton
53843412Snewton	case SVR4_SI_HW_SERIAL:
53943412Snewton		str = "0";
54043412Snewton		break;
54143412Snewton
54243412Snewton	case SVR4_SI_HW_PROVIDER:
54343412Snewton		str = ostype;
54443412Snewton		break;
54543412Snewton
54643412Snewton	case SVR4_SI_SRPC_DOMAIN:
54743412Snewton		str = domainname;
54843412Snewton		break;
54943412Snewton
55043412Snewton	case SVR4_SI_PLATFORM:
55143412Snewton#ifdef __i386__
55243412Snewton		str = "i86pc";
55343412Snewton#else
55443412Snewton		str = "unknown";
55543412Snewton#endif
55643412Snewton		break;
55743412Snewton
55843412Snewton	case SVR4_SI_KERB_REALM:
55943412Snewton		str = "unsupported";
56043412Snewton		break;
56143412Snewton#if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
56243412Snewton	case SVR4_SI_SET_HOSTNAME:
56346112Sphk		if ((error = suser(p)) != 0)
56443412Snewton			return error;
56543412Snewton		name = KERN_HOSTNAME;
56683366Sjulian		return kern_sysctl(&name, 1, 0, 0, SCARG(uap, buf), rlen, td);
56743412Snewton
56843412Snewton	case SVR4_SI_SET_SRPC_DOMAIN:
56946112Sphk		if ((error = suser(p)) != 0)
57043412Snewton			return error;
57143412Snewton		name = KERN_NISDOMAINNAME;
57283366Sjulian		return kern_sysctl(&name, 1, 0, 0, SCARG(uap, buf), rlen, td);
57343412Snewton#else
57443412Snewton	case SVR4_SI_SET_HOSTNAME:
57543412Snewton        case SVR4_SI_SET_SRPC_DOMAIN:
57643412Snewton		/* FALLTHROUGH */
57743412Snewton#endif
57843412Snewton	case SVR4_SI_SET_KERB_REALM:
57943412Snewton		return 0;
58043412Snewton
58143412Snewton	default:
58243412Snewton		DPRINTF(("Bad systeminfo command %d\n", SCARG(uap, what)));
58343412Snewton		return ENOSYS;
58443412Snewton	}
58543412Snewton
58643412Snewton	if (str) {
58743412Snewton		len = strlen(str) + 1;
58843412Snewton		if (len > rlen)
58943412Snewton			len = rlen;
59043412Snewton
59143412Snewton		if (SCARG(uap, buf)) {
59243412Snewton			error = copyout(str, SCARG(uap, buf), len);
59343412Snewton			if (error)
59443412Snewton				return error;
59543412Snewton			/* make sure we are NULL terminated */
59643412Snewton			buf[0] = '\0';
59743412Snewton			error = copyout(buf, &(SCARG(uap, buf)[len - 1]), 1);
59843412Snewton		}
59943412Snewton		else
60043412Snewton			error = 0;
60143412Snewton	}
60243412Snewton	/* XXX NetBSD has hostname setting stuff here.  Why would an emulator
60343412Snewton	   want to do that? */
60443412Snewton
60543412Snewton	*retval = len;
60643412Snewton	return error;
60743412Snewton}
60843412Snewton
60943412Snewtonint
61083366Sjuliansvr4_sys_utssys(td, uap)
61183366Sjulian	register struct thread *td;
61243412Snewton	struct svr4_sys_utssys_args *uap;
61343412Snewton{
61443412Snewton	switch (SCARG(uap, sel)) {
61543412Snewton	case 0:		/* uname(2)  */
61643412Snewton		{
61743412Snewton			struct svr4_sys_uname_args ua;
61843412Snewton			SCARG(&ua, name) = SCARG(uap, a1);
61983366Sjulian			return svr4_sys_uname(td, &ua);
62043412Snewton		}
62143412Snewton
62243412Snewton	case 2:		/* ustat(2)  */
62343412Snewton		{
62443412Snewton			struct svr4_ustat_args ua;
62543412Snewton			SCARG(&ua, dev) = (svr4_dev_t) SCARG(uap, a2);
62643412Snewton			SCARG(&ua, name) = SCARG(uap, a1);
62783366Sjulian			return svr4_ustat(td, &ua);
62843412Snewton		}
62943412Snewton
63043412Snewton	case 3:		/* fusers(2) */
63143412Snewton		return ENOSYS;
63243412Snewton
63343412Snewton	default:
63443412Snewton		return ENOSYS;
63543412Snewton	}
63643412Snewton	return ENOSYS;
63743412Snewton}
63843412Snewton
63943412Snewton
64043412Snewtonint
64183366Sjuliansvr4_sys_utime(td, uap)
64283366Sjulian	register struct thread *td;
64343412Snewton	struct svr4_sys_utime_args *uap;
64443412Snewton{
64543412Snewton	struct svr4_utimbuf ub;
64643412Snewton	struct timeval tbuf[2];
64743412Snewton	struct utimes_args ap;
64843412Snewton	int error;
64943412Snewton	caddr_t sg = stackgap_init();
65043412Snewton	void *ttp;
65143412Snewton
65283366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
65343412Snewton	SCARG(&ap, path) = SCARG(uap, path);
65443412Snewton	if (SCARG(uap, ubuf) != NULL) {
65543412Snewton		if ((error = copyin(SCARG(uap, ubuf), &ub, sizeof(ub))) != 0)
65643412Snewton			return error;
65743412Snewton		tbuf[0].tv_sec = ub.actime;
65843412Snewton		tbuf[0].tv_usec = 0;
65943412Snewton		tbuf[1].tv_sec = ub.modtime;
66043412Snewton		tbuf[1].tv_usec = 0;
66143412Snewton		ttp = stackgap_alloc(&sg, sizeof(tbuf));
66243412Snewton		error = copyout(tbuf, ttp, sizeof(tbuf));
66343412Snewton		if (error)
66443412Snewton			return error;
66543412Snewton		SCARG(&ap, tptr) = ttp;
66643412Snewton	}
66743412Snewton	else
66843412Snewton		SCARG(&ap, tptr) = NULL;
66983366Sjulian	return utimes(td, &ap);
67043412Snewton}
67143412Snewton
67243412Snewton
67343412Snewtonint
67483366Sjuliansvr4_sys_utimes(td, uap)
67583366Sjulian	register struct thread *td;
67643412Snewton	struct svr4_sys_utimes_args *uap;
67743412Snewton{
67843412Snewton	caddr_t sg = stackgap_init();
67983366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
68083366Sjulian	return utimes(td, (struct utimes_args *)uap);
68143412Snewton}
68243412Snewton
68343412Snewtonstatic int
68443412Snewtonsvr4_to_bsd_pathconf(name)
68543412Snewton	int name;
68643412Snewton{
68743412Snewton	switch (name) {
68843412Snewton	case SVR4_PC_LINK_MAX:
68943412Snewton	    	return _PC_LINK_MAX;
69043412Snewton
69143412Snewton	case SVR4_PC_MAX_CANON:
69243412Snewton		return _PC_MAX_CANON;
69343412Snewton
69443412Snewton	case SVR4_PC_MAX_INPUT:
69543412Snewton		return _PC_MAX_INPUT;
69643412Snewton
69743412Snewton	case SVR4_PC_NAME_MAX:
69843412Snewton		return _PC_NAME_MAX;
69943412Snewton
70043412Snewton	case SVR4_PC_PATH_MAX:
70143412Snewton		return _PC_PATH_MAX;
70243412Snewton
70343412Snewton	case SVR4_PC_PIPE_BUF:
70443412Snewton		return _PC_PIPE_BUF;
70543412Snewton
70643412Snewton	case SVR4_PC_NO_TRUNC:
70743412Snewton		return _PC_NO_TRUNC;
70843412Snewton
70943412Snewton	case SVR4_PC_VDISABLE:
71043412Snewton		return _PC_VDISABLE;
71143412Snewton
71243412Snewton	case SVR4_PC_CHOWN_RESTRICTED:
71343412Snewton		return _PC_CHOWN_RESTRICTED;
71443412Snewton	case SVR4_PC_SYNC_IO:
71543412Snewton#if defined(_PC_SYNC_IO)
71643412Snewton		return _PC_SYNC_IO;
71743412Snewton#else
71843412Snewton		return 0;
71943412Snewton#endif
72043412Snewton	case SVR4_PC_ASYNC_IO:
72143412Snewton	case SVR4_PC_PRIO_IO:
72243412Snewton		/* Not supported */
72343412Snewton		return 0;
72443412Snewton
72543412Snewton	default:
72643412Snewton		/* Invalid */
72743412Snewton		return -1;
72843412Snewton	}
72943412Snewton}
73043412Snewton
73143412Snewton
73243412Snewtonint
73383366Sjuliansvr4_sys_pathconf(td, uap)
73483366Sjulian	register struct thread *td;
73543412Snewton	struct svr4_sys_pathconf_args *uap;
73643412Snewton{
73749264Snewton	caddr_t		sg = stackgap_init();
73883366Sjulian	register_t	*retval = td->td_retval;
73943412Snewton
74083366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
74143412Snewton
74243412Snewton	SCARG(uap, name) = svr4_to_bsd_pathconf(SCARG(uap, name));
74343412Snewton
74443412Snewton	switch (SCARG(uap, name)) {
74543412Snewton	case -1:
74643412Snewton		*retval = -1;
74743412Snewton		return EINVAL;
74843412Snewton	case 0:
74943412Snewton		*retval = 0;
75043412Snewton		return 0;
75143412Snewton	default:
75283366Sjulian		return pathconf(td, (struct pathconf_args *)uap);
75343412Snewton	}
75443412Snewton}
75543412Snewton
75643412Snewton
75743412Snewtonint
75883366Sjuliansvr4_sys_fpathconf(td, uap)
75983366Sjulian	register struct thread *td;
76043412Snewton	struct svr4_sys_fpathconf_args *uap;
76143412Snewton{
76283366Sjulian        register_t	*retval = td->td_retval;
76343412Snewton
76443412Snewton	SCARG(uap, name) = svr4_to_bsd_pathconf(SCARG(uap, name));
76543412Snewton
76643412Snewton	switch (SCARG(uap, name)) {
76743412Snewton	case -1:
76843412Snewton		*retval = -1;
76943412Snewton		return EINVAL;
77043412Snewton	case 0:
77143412Snewton		*retval = 0;
77243412Snewton		return 0;
77343412Snewton	default:
77483366Sjulian		return fpathconf(td, (struct fpathconf_args *)uap);
77543412Snewton	}
77643412Snewton}
777