patch-2.1.44 linux/arch/sparc64/kernel/sys_sparc32.c

Next file: linux/arch/sparc64/kernel/sys_sunos32.c
Previous file: linux/arch/sparc64/kernel/sys_sparc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.26 1997/06/04 13:05:21 jj Exp $
+/* $Id: sys_sparc32.c,v 1.42 1997/07/05 09:52:36 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -8,6 +8,7 @@
  * environment.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/fs.h> 
 #include <linux/signal.h>
@@ -30,11 +31,13 @@
 #include <linux/ncp_fs.h>
 #include <linux/quota.h>
 #include <linux/file.h>
+#include <linux/module.h>
 
 #include <asm/types.h>
 #include <asm/poll.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
+#include <asm/fpumacro.h>
 
 /* As gcc will warn about casting u32 to some ptr, we have to cast it to
  * unsigned long first, and that's what is A() for.
@@ -372,11 +375,12 @@
 			switch (version) {
 			case 0: default: {
 				unsigned long raddr;
+				u32 *uptr = (u32 *) A(((u32)third));
 				err = sys_shmat (first, (char *)A(ptr), second, &raddr);
 				if (err)
 					goto out;
 				err = -EFAULT;
-				if(put_user (raddr, ((u32 *)A(third))))
+				if(put_user (raddr, uptr))
 					goto out;
 				err = 0;
 				goto out;
@@ -469,32 +473,6 @@
 	return err;
 }
 
-extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
-					 unsigned long prot, unsigned long flags,
-					 unsigned long fd, unsigned long off);
-
-asmlinkage unsigned long sys32_mmap(u32 addr, u32 len, u32 prot,
-				    u32 flags, u32 fd, u32 off)
-{
-	return sys_mmap((unsigned long)addr, (unsigned long)len,
-			(unsigned long)prot, (unsigned long)flags, 
-			(unsigned long)fd, (unsigned long)off);
-}
-
-extern asmlinkage int sys_bdflush(int func, long data);
-
-asmlinkage int sys32_bdflush(int func, s32 data)
-{
-	return sys_bdflush(func, (long)data);
-}
-
-extern asmlinkage int sys_uselib(const char * library);
-
-asmlinkage int sys32_uselib(u32 library)
-{
-	return sys_uselib((const char *)A(library));
-}
-
 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
 {
 	if(get_user(kfl->l_type, &ufl->l_type)		||
@@ -544,55 +522,6 @@
 	}
 }
 
-extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
-
-asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev)
-{
-	return sys_mknod((const char *)A(filename), mode, dev);
-}
-
-extern asmlinkage int sys_mkdir(const char * pathname, int mode);
-
-asmlinkage int sys32_mkdir(u32 pathname, int mode)
-{
-	return sys_mkdir((const char *)A(pathname), mode);
-}
-
-extern asmlinkage int sys_rmdir(const char * pathname);
-
-asmlinkage int sys32_rmdir(u32 pathname)
-{
-	return sys_rmdir((const char *)A(pathname));
-}
-
-extern asmlinkage int sys_unlink(const char * pathname);
-
-asmlinkage int sys32_unlink(u32 pathname)
-{
-	return sys_unlink((const char *)A(pathname));
-}
-
-extern asmlinkage int sys_symlink(const char * oldname, const char * newname);
-
-asmlinkage int sys32_symlink(u32 oldname, u32 newname)
-{
-	return sys_symlink((const char *)A(oldname), (const char *)A(newname));
-}
-
-extern asmlinkage int sys_link(const char * oldname, const char * newname);
-
-asmlinkage int sys32_link(u32 oldname, u32 newname)
-{
-	return sys_link((const char *)A(oldname), (const char *)A(newname));
-}
-
-extern asmlinkage int sys_rename(const char * oldname, const char * newname);
-
-asmlinkage int sys32_rename(u32 oldname, u32 newname)
-{
-	return sys_rename((const char *)A(oldname), (const char *)A(newname));
-}
-
 struct dqblk32 {
     __u32 dqb_bhardlimit;
     __u32 dqb_bsoftlimit;
@@ -701,20 +630,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_truncate(const char * path, unsigned long length);
-
-asmlinkage int sys32_truncate(u32 path, u32 length)
-{
-	return sys_truncate((const char *)A(path), (unsigned long)length);
-}
-
-extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
-
-asmlinkage int sys32_ftruncate(unsigned int fd, u32 length)
-{
-	return sys_ftruncate(fd, (unsigned long)length);
-}
-
 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
 
 asmlinkage int sys32_utime(u32 filename, u32 times)
@@ -741,96 +656,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_utimes(char * filename, struct timeval * utimes);
-
-asmlinkage int sys32_utimes(u32 filename, u32 utimes)
-{
-	/* struct timeval is the same :)) */
-	return sys_utimes((char *)A(filename), (struct timeval *)A(utimes));
-}
-
-extern asmlinkage int sys_access(const char * filename, int mode);
-
-asmlinkage int sys32_access(u32 filename, int mode)
-{
-	return sys_access((const char *)A(filename), mode);
-}
-
-extern asmlinkage int sys_chdir(const char * filename);
-
-asmlinkage int sys32_chdir(u32 filename)
-{
-	return sys_chdir((const char *)A(filename));
-}
-
-extern asmlinkage int sys_chroot(const char * filename);
-
-asmlinkage int sys32_chroot(u32 filename)
-{
-	return sys_chroot((const char *)A(filename));
-}
-
-extern asmlinkage int sys_chmod(const char * filename, mode_t mode);
-
-asmlinkage int sys32_chmod(u32 filename, __kernel_mode_t32 mode)
-{
-	return sys_chmod((const char *)A(filename), mode);
-}
-
-extern asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group);
-
-asmlinkage int sys32_chown(u32 filename, __kernel_uid_t32 user, __kernel_gid_t32 group)
-{
-	return sys_chown((const char *)A(filename), user, group);
-}
-
-extern asmlinkage int sys_open(const char * filename,int flags,int mode);
-
-asmlinkage int sys32_open(u32 filename, int flags, int mode)
-{
-	return sys_open((const char *)A(filename), flags, mode);
-}
-
-extern asmlinkage int sys_creat(const char * pathname, int mode);
-
-asmlinkage int sys32_creat(u32 pathname, int mode)
-{
-	return sys_creat((const char *)A(pathname), mode);
-}
-
-extern asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin);
-
-asmlinkage long sys32_lseek(unsigned int fd, s32 offset, unsigned int origin)
-{
-	return sys_lseek(fd, (off_t)offset, origin);
-}
-
-extern asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
-				 unsigned long offset_low,
-				 loff_t *result, unsigned int origin);
-
-asmlinkage int sys32_llseek(unsigned int fd, u32 offset_high,
-			    u32 offset_low, u32 result, unsigned int origin)
-{
-	/* loff_t is the same :)) */
-	return sys_llseek(fd, (unsigned long)offset_high, (unsigned long)offset_low,
-			  (loff_t *)A(result), origin);
-}
-
-extern asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count);
-
-asmlinkage long sys32_read(unsigned int fd, u32 buf, u32 count)
-{
-	return sys_read(fd, (char *)A(buf), (unsigned long)count);
-}
-
-extern asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count);
-
-asmlinkage long sys32_write(unsigned int fd, u32 buf, u32 count)
-{
-	return sys_write(fd, (const char *)A(buf), (unsigned long)count);
-}
-
 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
 
 typedef long (*IO_fn_t)(struct inode *, struct file *, char *, unsigned long);
@@ -1196,13 +1021,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout);
-
-asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout)
-{
-	return sys_poll((struct pollfd *)A(ufds), nfds, timeout);
-}
-
 static inline int putstat(struct stat32 *ubuf, struct stat *kbuf)
 {
 	if (put_user (kbuf->st_dev, &ubuf->st_dev)		||
@@ -1280,13 +1098,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz);
-
-asmlinkage int sys32_readlink(u32 path, u32 buf, int bufsiz)
-{
-	return sys_readlink((const char *)A(path), (char *)A(buf), bufsiz);
-}
-
 extern asmlinkage int sys_sysfs(int option, ...);
 
 asmlinkage int sys32_sysfs(int option, ...)
@@ -1312,42 +1123,162 @@
 	return ret;
 }
 
-extern asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf);
+struct ncp_mount_data32 {
+        int version;
+        unsigned int ncp_fd;
+        __kernel_uid_t32 mounted_uid;
+        __kernel_pid_t32 wdog_pid;
+        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+        unsigned int time_out;
+        unsigned int retry_count;
+        unsigned int flags;
+        __kernel_uid_t32 uid;
+        __kernel_gid_t32 gid;
+        __kernel_mode_t32 file_mode;
+        __kernel_mode_t32 dir_mode;
+};
 
-asmlinkage int sys32_ustat(dev_t dev, u32 ubuf)
+static void *do_ncp_super_data_conv(void *raw_data)
 {
-	/* ustat is the same :)) */
-	return sys_ustat(dev, (struct ustat *)A(ubuf));
+	struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
+	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+
+	n->dir_mode = n32->dir_mode;
+	n->file_mode = n32->file_mode;
+	n->gid = n32->gid;
+	n->uid = n32->uid;
+	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
+	n->wdog_pid = n32->wdog_pid;
+	n->mounted_uid = n32->mounted_uid;
+	return raw_data;
 }
 
-extern asmlinkage int sys_umount(char * name);
+struct smb_mount_data32 {
+        int version;
+        unsigned int fd;
+        __kernel_uid_t32 mounted_uid;
+        struct sockaddr_in addr;
+        char server_name[17];
+        char client_name[17];
+        char service[64];
+        char root_path[64];
+        char username[64];
+        char password[64];
+        char domain[64];
+        unsigned short max_xmit;
+        __kernel_uid_t32 uid;
+        __kernel_gid_t32 gid;
+        __kernel_mode_t32 file_mode;
+        __kernel_mode_t32 dir_mode;
+};
 
-asmlinkage int sys32_umount(u32 name)
+static void *do_smb_super_data_conv(void *raw_data)
 {
-	return sys_umount((char *)A(name));
-}
+	struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
 
-extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
-				unsigned long new_flags, void *data);
+	s->dir_mode = s32->dir_mode;
+	s->file_mode = s32->file_mode;
+	s->gid = s32->gid;
+	s->uid = s32->uid;
+	memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr)));
+	s->mounted_uid = s32->mounted_uid;
+	return raw_data;
+}
 
-asmlinkage int sys32_mount(u32 dev_name, u32 dir_name, u32 type, u32 new_flags, u32 data)
+static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
 {
-	return sys_mount((char *)A(dev_name), (char *)A(dir_name), (char *)A(type), 
-			 (unsigned long)new_flags, (void *)A(data));
+	int i;
+	unsigned long page;
+	struct vm_area_struct *vma;
+
+	*kernel = 0;
+	if(!user)
+		return 0;
+	vma = find_vma(current->mm, (unsigned long)user);
+	if(!vma || (unsigned long)user < vma->vm_start)
+		return -EFAULT;
+	if(!(vma->vm_flags & VM_READ))
+		return -EFAULT;
+	i = vma->vm_end - (unsigned long) user;
+	if(PAGE_SIZE <= (unsigned long) i)
+		i = PAGE_SIZE - 1;
+	if(!(page = __get_free_page(GFP_KERNEL)))
+		return -ENOMEM;
+	if(copy_from_user((void *) page, user, i)) {
+		free_page(page);
+		return -EFAULT;
+	}
+	*kernel = page;
+	return 0;
 }
 
-extern asmlinkage int sys_syslog(int type, char * bug, int count);
+extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
+				unsigned long new_flags, void *data);
 
-asmlinkage int sys32_syslog(int type, u32 bug, int count)
+#define SMBFS_NAME	"smbfs"
+#define NCPFS_NAME	"ncpfs"
+
+asmlinkage int sys32_mount(u32 dev_name, u32 dir_name, u32 type, u32 new_flags, u32 data)
 {
-	return sys_syslog(type, (char *)A(bug), count);
-}
+	unsigned long type_page;
+	int err, is_smb, is_ncp;
 
-extern asmlinkage int sys_personality(unsigned long personality);
+	if(!suser())
+		return -EPERM;
+	is_smb = is_ncp = 0;
+	err = copy_mount_stuff_to_kernel((const void *)A(type), &type_page);
+	if(err)
+		return err;
+	if(type_page) {
+		is_smb = !strcmp((char *)type_page, SMBFS_NAME);
+		is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
+	}
+	if(!is_smb && !is_ncp) {
+		if(type_page)
+			free_page(type_page);
+		return sys_mount((char *)A(dev_name), (char *)A(dir_name),
+				 (char *)A(type), (unsigned long)new_flags,
+				 (void *)A(data));
+	} else {
+		unsigned long dev_page, dir_page, data_page;
+		int old_fs;
 
-asmlinkage int sys32_personality(u32 personality)
-{
-	return sys_personality((unsigned long)personality);
+		err = copy_mount_stuff_to_kernel((const void *)A(dev_name), &dev_page);
+		if(err)
+			goto out;
+		err = copy_mount_stuff_to_kernel((const void *)A(dir_name), &dir_page);
+		if(err)
+			goto dev_out;
+		err = copy_mount_stuff_to_kernel((const void *)A(data), &data_page);
+		if(err)
+			goto dir_out;
+		if(is_ncp)
+			do_ncp_super_data_conv((void *)data_page);
+		else if(is_smb)
+			do_smb_super_data_conv((void *)data_page);
+		else
+			panic("Tell DaveM he fucked up...");
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_mount((char *)dev_page, (char *)dir_page,
+				(char *)type_page, (unsigned long)new_flags,
+				(void *)data_page);
+		set_fs(old_fs);
+
+		if(data_page)
+			free_page(data_page);
+	dir_out:
+		if(dir_page)
+			free_page(dir_page);
+	dev_out:
+		if(dev_page)
+			free_page(dev_page);
+	out:
+		if(type_page)
+			free_page(type_page);
+		return err;
+	}
 }
 
 struct rusage32 {
@@ -1416,13 +1347,6 @@
 	}
 }
 
-extern asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options);
-
-asmlinkage int sys32_waitpid(__kernel_pid_t32 pid, u32 stat_addr, int options)
-{
-	return sys_waitpid(pid, (unsigned int *)A(stat_addr), options);
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
@@ -1462,46 +1386,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_getitimer(int which, struct itimerval *value);
-
-asmlinkage int sys32_getitimer(int which, u32 value)
-{
-	/* itimerval is the same :)) */
-	return sys_getitimer(which, (struct itimerval *)A(value));
-}
-
-extern asmlinkage int sys_setitimer(int which, struct itimerval *value,
-				    struct itimerval *ovalue);
-
-asmlinkage int sys32_setitimer(int which, u32 value, u32 ovalue)
-{
-	return sys_setitimer(which, (struct itimerval *)A(value),
-			     (struct itimerval *)A(ovalue));
-}
-
-extern asmlinkage int sys_sched_setscheduler(pid_t pid, int policy,
-					     struct sched_param *param);
-
-asmlinkage int sys32_sched_setscheduler(__kernel_pid_t32 pid, int policy, u32 param)
-{
-	/* sched_param is the same :)) */
-	return sys_sched_setscheduler(pid, policy, (struct sched_param *)A(param));
-}
-
-extern asmlinkage int sys_sched_setparam(pid_t pid, struct sched_param *param);
-
-asmlinkage int sys32_sched_setparam(__kernel_pid_t32 pid, u32 param)
-{
-	return sys_sched_setparam(pid, (struct sched_param *)A(param));
-}
-
-extern asmlinkage int sys_sched_getparam(pid_t pid, struct sched_param *param);
-
-asmlinkage int sys32_sched_getparam(__kernel_pid_t32 pid, u32 param)
-{
-	return sys_sched_getparam(pid, (struct sched_param *)A(param));
-}
-
 struct timespec32 {
 	s32    tv_sec;
 	s32    tv_nsec;
@@ -1577,25 +1461,29 @@
 	return ret;
 }
 
-extern asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler);
+extern asmlinkage int sys_setreuid(uid_t ruid, uid_t euid);
 
-asmlinkage unsigned long sys32_signal(int signum, u32 handler)
+asmlinkage int sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
 {
-	return sys_signal(signum, (__sighandler_t)A(handler));
-}
+	uid_t sruid, seuid;
 
-extern asmlinkage int sys_reboot(int magic1, int magic2, int cmd, void * arg);
-
-asmlinkage int sys32_reboot(int magic1, int magic2, int cmd, u32 arg)
-{
-	return sys_reboot(magic1, magic2, cmd, (void *)A(arg));
+	sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
+	seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
+	return sys_setreuid(sruid, seuid);
 }
 
-extern asmlinkage int sys_acct(const char *name);
+extern asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
 
-asmlinkage int sys32_acct(u32 name)
+asmlinkage int sys32_setresuid(__kernel_uid_t32 ruid,
+			       __kernel_uid_t32 euid,
+			       __kernel_uid_t32 suid)
 {
-	return sys_acct((const char *)A(name));
+	uid_t sruid, seuid, ssuid;
+
+	sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
+	seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
+	ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
+	return sys_setresuid(sruid, seuid, ssuid);
 }
 
 extern asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
@@ -1654,7 +1542,7 @@
 	set_fs (KERNEL_DS);
 	ret = sys_getgroups(gidsetsize, gl);
 	set_fs (old_fs);
-	if (ret > 0 && ret <= NGROUPS)
+	if (gidsetsize && ret > 0 && ret <= NGROUPS)
 		for (i = 0; i < ret; i++, grouplist += sizeof(__kernel_gid_t32))
 			if (__put_user (gl[i], (__kernel_gid_t32 *)A(grouplist)))
 				return -EFAULT;
@@ -1680,41 +1568,8 @@
 	return ret;
 }
 
-extern asmlinkage int sys_newuname(struct new_utsname * name);
-
-asmlinkage int sys32_newuname(u32 name)
-{
-	/* utsname is the same :)) */
-	return sys_newuname((struct new_utsname *)A(name));
-}
-
-extern asmlinkage int sys_olduname(struct oldold_utsname * name);
-
-asmlinkage int sys32_olduname(u32 name)
-{
-	return sys_olduname((struct oldold_utsname *)A(name));
-}
-
-extern asmlinkage int sys_sethostname(char *name, int len);
-
-asmlinkage int sys32_sethostname(u32 name, int len)
-{
-	return sys_sethostname((char *)A(name), len);
-}
-
-extern asmlinkage int sys_gethostname(char *name, int len);
-
-asmlinkage int sys32_gethostname(u32 name, int len)
-{
-	return sys_gethostname((char *)A(name), len);
-}
-
-extern asmlinkage int sys_setdomainname(char *name, int len);
-
-asmlinkage int sys32_setdomainname(u32 name, int len)
-{
-	return sys_setdomainname((char *)A(name), len);
-}
+#define RLIM_INFINITY32	0x7fffffff
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
 	s32	rlim_cur;
@@ -1733,8 +1588,8 @@
 	ret = sys_getrlimit(resource, &r);
 	set_fs (old_fs);
 	if (!ret && (
-	    put_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
-	    __put_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max))))
+	    put_user (RESOURCE32(r.rlim_cur), &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
+	    __put_user (RESOURCE32(r.rlim_max), &(((struct rlimit32 *)A(rlim))->rlim_max))))
 		return -EFAULT;
 	return ret;
 }
@@ -1751,6 +1606,10 @@
 	if (get_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
 	    __get_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max)))
 		return -EFAULT;
+	if (r.rlim_cur == RLIM_INFINITY32)
+		r.rlim_cur = RLIM_INFINITY;
+	if (r.rlim_max == RLIM_INFINITY32)
+		r.rlim_max = RLIM_INFINITY;
 	set_fs (KERNEL_DS);
 	ret = sys_setrlimit(resource, &r);
 	set_fs (old_fs);
@@ -1772,28 +1631,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_time(int * tloc);
-
-asmlinkage int sys32_time(u32 tloc)
-{
-	return sys_time((int *)A(tloc));
-}
-
-extern asmlinkage int sys_gettimeofday(struct timeval *tv, struct timezone *tz);
-
-asmlinkage int sys32_gettimeofday(u32 tv, u32 tz)
-{
-	/* both timeval and timezone are ok :)) */
-	return sys_gettimeofday((struct timeval *)A(tv), (struct timezone *)A(tz));
-}
-
-extern asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz);
-
-asmlinkage int sys32_settimeofday(u32 tv, u32 tz)
-{
-	return sys_settimeofday((struct timeval *)A(tv), (struct timezone *)A(tz));
-}
-
 struct timex32 {
 	unsigned int modes;
 	s32 offset;
@@ -1865,170 +1702,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_msync(unsigned long start, size_t len, int flags);
-
-asmlinkage int sys32_msync(u32 start, __kernel_size_t32 len, int flags)
-{
-	return sys_msync((unsigned long)start, (size_t)len, flags);
-}
-
-extern asmlinkage int sys_mlock(unsigned long start, size_t len);
-
-asmlinkage int sys32_mlock(u32 start, __kernel_size_t32 len)
-{
-	return sys_mlock((unsigned long)start, (size_t)len);
-}
-
-extern asmlinkage int sys_munlock(unsigned long start, size_t len);
-
-asmlinkage int sys32_munlock(u32 start, __kernel_size_t32 len)
-{
-	return sys_munlock((unsigned long)start, (size_t)len);
-}
-
-extern asmlinkage unsigned long sys_brk(unsigned long brk);
-
-asmlinkage unsigned long sparc32_brk(u32 brk)
-{
-	return sys_brk((unsigned long)brk);
-}
-
-extern asmlinkage int sys_munmap(unsigned long addr, size_t len);
-
-asmlinkage int sys32_munmap(u32 addr, __kernel_size_t32 len)
-{
-	return sys_munmap((unsigned long)addr, (size_t)len);
-}
-
-extern asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot);
-
-asmlinkage int sys32_mprotect(u32 start, __kernel_size_t32 len, u32 prot)
-{
-	return sys_mprotect((unsigned long)start, (size_t)len, (unsigned long)prot);
-}
-
-extern asmlinkage unsigned long sys_mremap(unsigned long addr, unsigned long old_len,
-					   unsigned long new_len, unsigned long flags);
-
-asmlinkage unsigned long sys32_mremap(u32 addr, u32 old_len, u32 new_len, u32 flags)
-{
-	return sys_mremap((unsigned long)addr, (unsigned long)old_len,
-			  (unsigned long)new_len, (unsigned long)flags);
-}
-
-extern asmlinkage int sys_swapoff(const char * specialfile);
-
-asmlinkage int sys32_swapoff(u32 specialfile)
-{
-	return sys_swapoff((const char *)A(specialfile));
-}
-
-extern asmlinkage int sys_swapon(const char * specialfile, int swap_flags);
-
-asmlinkage int sys32_swapon(u32 specialfile, int swap_flags)
-{
-	return sys_swapon((const char *)A(specialfile), swap_flags);
-}
-
-extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
-
-asmlinkage inline int sys32_bind(int fd, u32 umyaddr, int addrlen)
-{
-	/* sockaddr is the same :)) */
-	return sys_bind(fd, (struct sockaddr *)A(umyaddr), addrlen);
-}
-
-extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr,
-				 int *upeer_addrlen);
-
-asmlinkage inline int sys32_accept(int fd, u32 upeer_sockaddr, u32 upeer_addrlen)
-{
-	return sys_accept(fd, (struct sockaddr *)A(upeer_sockaddr),
-			  (int *)A(upeer_addrlen));
-}
-
-extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
-
-asmlinkage inline int sys32_connect(int fd, u32 uservaddr, int addrlen)
-{
-	return sys_connect(fd, (struct sockaddr *)A(uservaddr), addrlen);
-}
-
-extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr,
-				      int *usockaddr_len);
-
-asmlinkage int sys32_getsockname(int fd, u32 usockaddr, u32 usockaddr_len)
-{
-	return sys_getsockname(fd, (struct sockaddr *)A(usockaddr),
-			       (int *)A(usockaddr_len));
-}
-
-extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr,
-				      int *usockaddr_len);
-
-asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len)
-{
-	return sys_getpeername(fd, (struct sockaddr *)A(usockaddr),
-			       (int *)A(usockaddr_len));
-}
-
-extern asmlinkage int sys_send(int fd, void * buff, size_t len, unsigned flags);
-
-asmlinkage inline int sys32_send(int fd, u32 buff,
-				 __kernel_size_t32 len, unsigned flags)
-{
-	return sys_send(fd, (void *)A(buff), (size_t)len, flags);
-}
-
-extern asmlinkage int sys_sendto(int fd, void * buff, size_t len, unsigned flags,
-				 struct sockaddr *addr, int addr_len);
-
-asmlinkage inline int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
-				   unsigned flags, u32 addr, int addr_len)
-{
-	return sys_sendto(fd, (void *)A(buff), (size_t)len, flags,
-			  (struct sockaddr *)A(addr), addr_len);
-}
-
-extern asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags);
-
-asmlinkage inline int sys32_recv(int fd, u32 ubuf,
-				 __kernel_size_t32 size, unsigned flags)
-{
-	return sys_recv(fd, (void *)A(ubuf), (size_t)size, flags);
-}
-
-extern asmlinkage int sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags,
-				   struct sockaddr *addr, int *addr_len); 
-
-asmlinkage inline int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
-				     unsigned flags, u32 addr, u32 addr_len)
-{
-	return sys_recvfrom(fd, (void *)A(ubuf), (size_t)size, flags,
-			    (struct sockaddr *)A(addr), (int *)A(addr_len));
-}
- 
-extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
-				     char *optval, int optlen);
-
-asmlinkage inline int sys32_setsockopt(int fd, int level, int optname,
-				       u32 optval, int optlen)
-{
-	/* XXX handle ip_fw32->ip_fw conversion for IP firewalling and accounting.
-	       Do it using some macro in ip_sockglue.c
-	   Other optval arguments are mostly just ints or 32<->64bit transparent */
-	return sys_setsockopt(fd, level, optname, (char *)A(optval), optlen);
-}
-
-extern asmlinkage int sys_getsockopt(int fd, int level, int optname,
-				     char *optval, int *optlen);
-
-asmlinkage inline int sys32_getsockopt(int fd, int level, int optname,
-				       u32 optval, u32 optlen)
-{
-	return sys_getsockopt(fd, level, optname, (char *)A(optval), (int *)A(optlen));
-}
-
 /* XXX This really belongs in some header file... -DaveM */
 #define MAX_SOCK_ADDR	128		/* 108 for Unix domain - 
 					   16 for IP, 16 for IPX,
@@ -2293,6 +1966,24 @@
                                 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
 #undef AL
 
+extern asmlinkage int sys32_bind(int fd, u32 umyaddr, int addrlen);
+extern asmlinkage int sys32_connect(int fd, u32 uservaddr, int addrlen);
+extern asmlinkage int sys32_accept(int fd, u32 upeer_sockaddr, u32 upeer_addrlen);
+extern asmlinkage int sys32_getsockname(int fd, u32 usockaddr, u32 usockaddr_len);
+extern asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len);
+extern asmlinkage int sys32_send(int fd, u32 buff, __kernel_size_t32 len,
+				 unsigned flags);
+extern asmlinkage int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
+				   unsigned flags, u32 addr, int addr_len);
+extern asmlinkage int sys32_recv(int fd, u32 ubuf, __kernel_size_t32 size,
+				 unsigned flags);
+extern asmlinkage int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
+				     unsigned flags, u32 addr, u32 addr_len);
+extern asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+				       u32 optval, int optlen);
+extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
+				       u32 optval, u32 optlen);
+
 extern asmlinkage int sys_socket(int family, int type, int protocol);
 extern asmlinkage int sys_socketpair(int family, int type, int protocol,
 				     int usockvec[2]);
@@ -2389,7 +2080,7 @@
 		old_sa.sa_mask = (sigset_t32)(p->sa_mask);
 		old_sa.sa_flags = (unsigned)(p->sa_flags);
 		old_sa.sa_restorer = (unsigned)(u64)(p->sa_restorer);
-		if (copy_to_user(A(oldaction), p, sizeof(struct sigaction32)))
+		if (copy_to_user(A(oldaction), &old_sa, sizeof(struct sigaction32)))
 			goto out;	
 	}
 
@@ -2407,14 +2098,6 @@
 	return err;
 }
 
-extern asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp);
-
-asmlinkage int sys32_nfsservctl(int cmd, u32 argp, u32 resp)
-{
-	/* XXX handle argp and resp args */
-	return sys_nfsservctl(cmd, (void *)A(argp), (void *)A(resp));
-}
-
 /*
  * count32() counts the number of arguments/envelopes
  */
@@ -2550,74 +2233,219 @@
         	(u32 *)A((u32)regs->u_regs[base + UREG_I1]),
         	(u32 *)A((u32)regs->u_regs[base + UREG_I2]), regs);
         putname(filename);
+	if(!error) {
+		fprs_write(0);
+		regs->fprs = 0;
+	}
         return error;
 }
 
-/* Modules will be supported with 64bit modutils only */
-asmlinkage int sys32_no_modules(void)
+#ifdef CONFIG_MODULES
+
+extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
+
+asmlinkage unsigned long sys32_create_module(u32 name_user, __kernel_size_t32 size)
 {
-	return -ENOSYS;
+	return sys_create_module((const char *)A(name_user), (size_t)size);
 }
 
-struct ncp_mount_data32 {
-        int version;
-        unsigned int ncp_fd;
-        __kernel_uid_t32 mounted_uid;
-        __kernel_pid_t32 wdog_pid;
-        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
-        unsigned int time_out;
-        unsigned int retry_count;
-        unsigned int flags;
-        __kernel_uid_t32 uid;
-        __kernel_gid_t32 gid;
-        __kernel_mode_t32 file_mode;
-        __kernel_mode_t32 dir_mode;
-};
+extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
 
-void *do_ncp_super_data_conv(void *raw_data)
+/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
+ * module structure, even if from 32bit modutils... Why to pollute kernel... :))
+ */
+asmlinkage int sys32_init_module(u32 nameuser, u32 mod_user)
 {
-	struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
-	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+	return sys_init_module((const char *)A(nameuser), (struct module *)A(mod_user));
+}
 
-	n->dir_mode = n32->dir_mode;
-	n->file_mode = n32->file_mode;
-	n->gid = n32->gid;
-	n->uid = n32->uid;
-	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
-	n->wdog_pid = n32->wdog_pid;
-	n->mounted_uid = n32->mounted_uid;
-	return raw_data;
+extern asmlinkage int sys_delete_module(const char *name_user);
+
+asmlinkage int sys32_delete_module(u32 name_user)
+{
+	return sys_delete_module((const char *)A(name_user));
 }
 
-struct smb_mount_data32 {
-        int version;
-        unsigned int fd;
-        __kernel_uid_t32 mounted_uid;
-        struct sockaddr_in addr;
-        char server_name[17];
-        char client_name[17];
-        char service[64];
-        char root_path[64];
-        char username[64];
-        char password[64];
-        char domain[64];
-        unsigned short max_xmit;
-        __kernel_uid_t32 uid;
-        __kernel_gid_t32 gid;
-        __kernel_mode_t32 file_mode;
-        __kernel_mode_t32 dir_mode;
+struct module_info32 {
+	u32 addr;
+	u32 size;
+	u32 flags;
+	s32 usecount;
 };
 
-void *do_smb_super_data_conv(void *raw_data)
+extern asmlinkage int sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t *ret);
+
+asmlinkage int sys32_query_module(u32 name_user, int which, u32 buf, __kernel_size_t32 bufsize, u32 retv)
 {
-	struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
-	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
+	char *buff;
+	unsigned long old_fs = get_fs();
+	size_t val;
+	int ret, i, j;
+	unsigned long *p;
+	char *usernam = NULL;
+	int bufsiz = bufsize;
+	struct module_info mi;
+	
+	switch (which) {
+	case 0:	return sys_query_module ((const char *)A(name_user), which, (char *)A(buf), (size_t)bufsize, (size_t *)A(retv));
+	case QM_SYMBOLS:
+		bufsiz <<= 1;
+	case QM_MODULES:
+	case QM_REFS:
+	case QM_DEPS:
+		if (name_user && (ret = getname32 (name_user, &usernam)))
+			return ret;
+		buff = kmalloc (bufsiz, GFP_KERNEL);
+		if (!buff) {
+			if (name_user) putname32 (usernam);
+			return -ENOMEM;
+		}
+qmsym_toshort:
+		set_fs (KERNEL_DS);
+		ret = sys_query_module (usernam, which, buff, bufsiz, &val);
+		set_fs (old_fs);
+		if (which != QM_SYMBOLS) {
+			if (ret == -ENOSPC || !ret) {
+				if (put_user (val, (__kernel_size_t32 *)A(retv)))
+					ret = -EFAULT;
+			}
+			if (!ret) {
+				if (copy_to_user ((char *)A(buf), buff, bufsize))
+					ret = -EFAULT;
+			}
+		} else {
+			if (ret == -ENOSPC) {
+				if (put_user (2 * val, (__kernel_size_t32 *)A(retv)))
+					ret = -EFAULT;
+			}
+			p = (unsigned long *)buff;
+			if (!ret) {
+				if (put_user (val, (__kernel_size_t32 *)A(retv)))
+					ret = -EFAULT;
+			}
+			if (!ret) {
+				j = val * 8;
+				for (i = 0; i < val; i++, p += 2) {
+					if (bufsize < (2 * sizeof (u32))) {
+						bufsiz = 0;
+						goto qmsym_toshort;
+					}
+					if (put_user (p[0], (u32 *)A(buf)) ||
+				    	    __put_user (p[1] - j, (((u32 *)A(buf))+1))) {
+						ret = -EFAULT;
+						break;
+					}
+					bufsize -= (2 * sizeof (u32));
+					buf += (2 * sizeof (u32));
+				}
+			}
+			if (!ret && val) {
+				char *strings = buff + ((unsigned long *)buff)[1];
+				j = *(p - 1) - ((unsigned long *)buff)[1];
+				j = j + strlen (buff + j) + 1;
+				if (bufsize < j) {
+					bufsiz = 0;
+					goto qmsym_toshort;
+				}
+				if (copy_to_user ((char *)A(buf), strings, j))
+					ret = -EFAULT;
+			}
+		}
+		kfree (buff);
+		if (name_user) putname32 (usernam);
+		return ret;
+	case QM_INFO:
+		if (name_user && (ret = getname32 (name_user, &usernam)))
+			return ret;
+		set_fs (KERNEL_DS);
+		ret = sys_query_module (usernam, which, (char *)&mi, sizeof (mi), &val);
+		set_fs (old_fs);
+		if (!ret) {
+			if (put_user (sizeof (struct module_info32), (__kernel_size_t32 *)A(retv)))
+				ret = -EFAULT;
+			else if (bufsize < sizeof (struct module_info32))
+				ret = -ENOSPC;
+		}
+		if (!ret) {
+			if (put_user (mi.addr, &(((struct module_info32 *)A(buf))->addr)) ||
+			    __put_user (mi.size, &(((struct module_info32 *)A(buf))->size)) ||
+			    __put_user (mi.flags, &(((struct module_info32 *)A(buf))->flags)) ||
+			    __put_user (mi.usecount, &(((struct module_info32 *)A(buf))->usecount)))
+				ret = -EFAULT;
+		}
+		if (name_user) putname32 (usernam);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
 
-	s->dir_mode = s32->dir_mode;
-	s->file_mode = s32->file_mode;
-	s->gid = s32->gid;
-	s->uid = s32->uid;
-	memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr)));
-	s->mounted_uid = s32->mounted_uid;
-	return raw_data;
+struct kernel_sym32 {
+	u32 value;
+	char name[60];
+};
+		 
+extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+
+asmlinkage int sys32_get_kernel_syms(u32 table)
+{
+	int len, i;
+	struct kernel_sym *tbl;
+	unsigned long old_fs;
+	
+	len = sys_get_kernel_syms(NULL);
+	if (!table) return len;
+	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+	if (!tbl) return -ENOMEM;
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	sys_get_kernel_syms(tbl);
+	set_fs (old_fs);
+	for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
+		if (put_user (tbl[i].value, &(((struct kernel_sym32 *)A(table))->value)) ||
+		    copy_to_user (((struct kernel_sym32 *)A(table))->name, tbl[i].name, 60))
+			break;
+	}
+	kfree (tbl);
+	return i;
+}
+
+#else /* CONFIG_MODULES */
+
+asmlinkage unsigned long
+sys_create_module(const char *name_user, size_t size)
+{
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys_init_module(const char *name_user, struct module *mod_user)
+{
+	return -ENOSYS;
 }
+
+asmlinkage int
+sys_delete_module(const char *name_user)
+{
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
+		 size_t *ret)
+{
+	/* Let the program know about the new interface.  Not that
+	   it'll do them much good.  */
+	if (which == 0)
+		return 0;
+
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys_get_kernel_syms(struct kernel_sym *table)
+{
+	return -ENOSYS;
+}
+
+#endif  /* CONFIG_MODULES */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov