Index: emulation/43bsd/43bsd_socket.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/43bsd/43bsd_socket.c,v
retrieving revision 1.3
diff -u -u -r1.3 43bsd_socket.c
--- emulation/43bsd/43bsd_socket.c	3 Oct 2003 00:04:04 -0000	1.3
+++ emulation/43bsd/43bsd_socket.c	7 Oct 2003 02:33:44 -0000
@@ -207,11 +207,11 @@
 	struct thread *td = curthread;
 	struct msghdr msg;
 	struct uio auio;
-	struct iovec aiov[UIO_SMALLIOV], *iov = NULL, *iovp;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
 	struct sockaddr *sa = NULL;
 	struct mbuf *control = NULL;
 	struct cmsghdr *cm;
-	int error, i;
+	int error;
 
 	error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg));
 	if (error)
@@ -230,31 +230,13 @@
 	/*
 	 * Populate auio.
 	 */
-	if (msg.msg_iovlen >= UIO_MAXIOV) {
-		error =  EMSGSIZE;
-		goto cleanup;
-	}
-	if (msg.msg_iovlen >= UIO_SMALLIOV) {
-		MALLOC(iov, struct iovec *,
-		    sizeof(struct iovec) * msg.msg_iovlen, M_IOV,
-		    M_WAITOK);
-	} else {
-		iov = aiov;
-	}
-	error = copyin(msg.msg_iov, iov, msg.msg_iovlen * sizeof(struct iovec));
+	error = iovec_copyin(msg.msg_iov, &iov, aiov, msg.msg_iovlen,
+	    &auio.uio_resid);
 	if (error)
 		goto cleanup;
 	auio.uio_iov = iov;
 	auio.uio_iovcnt = msg.msg_iovlen;
 	auio.uio_offset = 0;
-	auio.uio_resid = 0;
-	for (i = 0, iovp = auio.uio_iov; i < msg.msg_iovlen; i++, iovp++) {
-		auio.uio_resid += iovp->iov_len;
-		if (auio.uio_resid < 0) {
-			error = EINVAL;
-			goto cleanup;
-		}
-	}
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_rw = UIO_WRITE;
 	auio.uio_td = td;
@@ -304,8 +286,7 @@
 cleanup:
 	if (sa)
 		FREE(sa, M_SONAME);
-	if (iov != aiov)
-		FREE(iov, M_IOV);
+	iovec_free(&iov, aiov);
 	return (error);
 }
 
@@ -386,12 +367,12 @@
 	struct thread *td = curthread;
 	struct msghdr msg;
 	struct uio auio;
-	struct iovec aiov[UIO_SMALLIOV], *iov = NULL, *iovp;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
 	struct mbuf *m, *control;
 	struct sockaddr *sa = NULL;
 	caddr_t ctlbuf;
 	socklen_t *ufromlenp, *ucontrollenp;
-	int error, fromlen, controllen, len, i, flags, *uflagsp;
+	int error, fromlen, controllen, len, flags, *uflagsp;
 
 	/*
 	 * This copyin handles everything except the iovec.
@@ -415,28 +396,13 @@
 	/*
 	 * Populate auio.
 	 */
-	if (msg.msg_iovlen >= UIO_MAXIOV)
-		return (EMSGSIZE);
-	if (msg.msg_iovlen >= UIO_SMALLIOV) {
-		MALLOC(iov, struct iovec *,
-		    sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
-	} else {
-		iov = aiov;
-	}
-	error = copyin(msg.msg_iov, iov, msg.msg_iovlen * sizeof(struct iovec));
+	error = iovec_copyin(msg.msg_iov, &iov, aiov, msg.msg_iovlen,
+	    &auio.uio_resid);
 	if (error)
-		goto cleanup;
+		return (error);
 	auio.uio_iov = iov;
 	auio.uio_iovcnt = msg.msg_iovlen;
 	auio.uio_offset = 0;
-	auio.uio_resid = 0;
-	for (i = 0, iovp = auio.uio_iov; i < msg.msg_iovlen; i++, iovp++) {
-		auio.uio_resid += iovp->iov_len;
-		if (auio.uio_resid < 0) {
-			error = EINVAL;
-			goto cleanup;
-		}
-	}
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_rw = UIO_READ;
 	auio.uio_td = td;
@@ -516,8 +482,7 @@
 cleanup:
 	if (sa)
 		FREE(sa, M_SONAME);
-	if (iov != aiov)
-		FREE(iov, M_IOV);
+	iovec_free(&iov, aiov);
 	if (control)
 		m_freem(control);
 	return (error);
Index: emulation/linux/linux_socket.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/linux_socket.c,v
retrieving revision 1.12
diff -u -u -r1.12 linux_socket.c
--- emulation/linux/linux_socket.c	4 Oct 2003 02:12:51 -0000	1.12
+++ emulation/linux/linux_socket.c	7 Oct 2003 03:04:07 -0000
@@ -839,10 +839,10 @@
 	struct thread *td = curthread;
 	struct msghdr msg;
 	struct uio auio;
-	struct iovec aiov[UIO_SMALLIOV], *iov = NULL, *iovp;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
 	struct sockaddr *sa = NULL;
 	struct mbuf *control = NULL;
-	int error, i;
+	int error;
 
 	error = copyin(args, &linux_args, sizeof(linux_args));
 	if (error)
@@ -864,30 +864,13 @@
 	/*
 	 * Populate auio.
 	 */
-	if (msg.msg_iovlen >= UIO_MAXIOV) {
-		error = EMSGSIZE;
-		goto cleanup;
-	}
-	if (msg.msg_iovlen >= UIO_SMALLIOV) {
-		MALLOC(iov, struct iovec *,
-		    sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
-	} else {
-		iov = aiov;
-	}
-	error = copyin(msg.msg_iov, iov, msg.msg_iovlen * sizeof(struct iovec));
+	error = iovec_copyin(msg.msg_iov, &iov, aiov, msg.msg_iovlen,
+	   &auio.uio_resid);
 	if (error)
 		goto cleanup;
 	auio.uio_iov = iov;
 	auio.uio_iovcnt = msg.msg_iovlen;
 	auio.uio_offset = 0;
-	auio.uio_resid = 0;
-	for (i = 0, iovp = auio.uio_iov; i < msg.msg_iovlen; i++, iovp++) {
-		auio.uio_resid += iovp->iov_len;
-		if (auio.uio_resid < 0) {
-			error = EINVAL;
-			goto cleanup;
-		}
-	}
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_rw = UIO_WRITE;
 	auio.uio_td = td;
@@ -934,8 +917,7 @@
 cleanup:
 	if (sa)
 		FREE(sa, M_SONAME);
-	if (iov != aiov)
-		FREE(iov, M_IOV);
+	iovec_free(&iov, aiov);
 	return (error);
 }
 
@@ -952,12 +934,12 @@
 	struct thread *td = curthread;
 	struct msghdr msg;
 	struct uio auio;
-	struct iovec aiov[UIO_SMALLIOV], *iov = NULL, *iovp;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
 	struct mbuf *m, *control;
 	struct sockaddr *sa = NULL;
 	caddr_t ctlbuf;
 	socklen_t *ufromlenp, *ucontrollenp;
-	int error, fromlen, controllen, len, i, flags, *uflagsp;
+	int error, fromlen, controllen, len, flags, *uflagsp;
 
 	error = copyin(args, &linux_args, sizeof(linux_args));
 	if (error)
@@ -982,28 +964,13 @@
 	/*
 	 * Populate auio.
 	 */
-	if (msg.msg_iovlen >= UIO_MAXIOV)
-		return (EMSGSIZE);
-	if (msg.msg_iovlen >= UIO_SMALLIOV) {
-		MALLOC(iov, struct iovec *,
-		    sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
-	} else {
-		iov = aiov;
-	}
-	error = copyin(msg.msg_iov, iov, msg.msg_iovlen * sizeof(struct iovec));
+	error = iovec_copyin(msg.msg_iov, &iov, aiov, msg.msg_iovlen,
+	    &auio.uio_resid);
 	if (error)
-		goto cleanup;
+		return (error);
 	auio.uio_iov = iov;
 	auio.uio_iovcnt = msg.msg_iovlen;
 	auio.uio_offset = 0;
-	auio.uio_resid = 0;
-	for (i = 0, iovp = auio.uio_iov; i < msg.msg_iovlen; i++, iovp++) {
-		auio.uio_resid += iovp->iov_len;
-		if (auio.uio_resid < 0) {
-			error = EINVAL;
-			goto cleanup;
-		}
-	}
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_rw = UIO_READ;
 	auio.uio_td = td;
@@ -1075,8 +1042,7 @@
 cleanup:
 	if (sa)
 		FREE(sa, M_SONAME);
-	if (iov != aiov)
-		FREE(iov, M_IOV);
+	iovec_free(&iov, aiov);
 	if (control)
 		m_freem(control);
 	return (error);
Index: emulation/svr4/svr4_stream.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/svr4/svr4_stream.c,v
retrieving revision 1.9
diff -u -u -r1.9 svr4_stream.c
--- emulation/svr4/svr4_stream.c	27 Aug 2003 06:07:10 -0000	1.9
+++ emulation/svr4/svr4_stream.c	3 Oct 2003 01:40:15 -0000
@@ -201,10 +201,18 @@
 			error = EINVAL;
 			goto bad;
 		}
-		error = sockargs(&control, mp->msg_control,
-		    mp->msg_controllen, MT_CONTROL);
-		if (error)
+		control = m_get(M_WAIT, MT_CONTROL);
+		if (control == NULL) {
+			error = ENOBUFS;
 			goto bad;
+		}
+		control->m_len = mp->msg_controllen;
+		error = copyin(mp->msg_control, mtod(control, caddr_t),
+		    mp->msg_controllen);
+		if (error) {
+			m_free(control);
+			goto bad;
+		}
 	} else {
 		control = 0;
 	}
Index: kern/init_sysent.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/init_sysent.c,v
retrieving revision 1.7
diff -u -u -r1.7 init_sysent.c
--- kern/init_sysent.c	12 Aug 2003 02:36:15 -0000	1.7
+++ kern/init_sysent.c	7 Oct 2003 02:53:05 -0000
@@ -2,7 +2,7 @@
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/kern/init_sysent.c,v 1.7 2003/08/12 02:36:15 dillon Exp $
+ * $DragonFly$
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -358,7 +358,7 @@
 	{ AS(sched_get_priority_min_args), (sy_call_t *)sched_get_priority_min },	/* 333 = sched_get_priority_min */
 	{ AS(sched_rr_get_interval_args), (sy_call_t *)sched_rr_get_interval },	/* 334 = sched_rr_get_interval */
 	{ AS(utrace_args), (sy_call_t *)utrace },	/* 335 = utrace */
-	{ compat(AS(osendfile_args),sendfile) },	/* 336 = old sendfile */
+	{ 0, (sy_call_t *)nosys },			/* 336 = obsolete freebsd4_sendfile */
 	{ AS(kldsym_args), (sy_call_t *)kldsym },	/* 337 = kldsym */
 	{ AS(jail_args), (sy_call_t *)jail },		/* 338 = jail */
 	{ 0, (sy_call_t *)nosys },			/* 339 = pioctl */
Index: kern/kern_subr.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/kern_subr.c,v
retrieving revision 1.11
diff -u -u -r1.11 kern_subr.c
--- kern/kern_subr.c	2 Oct 2003 19:21:06 -0000	1.11
+++ kern/kern_subr.c	7 Oct 2003 02:27:19 -0000
@@ -446,3 +446,41 @@
 	*nentries = hashsize;
 	return (hashtbl);
 }
+
+/*
+ * Copyin an iovec.  If the iovec array fits, use the preallocated small
+ * iovec structure.  If it is too big, dynamically allocate an iovec array
+ * of sufficient size.
+ */
+int
+iovec_copyin(struct iovec *uiov, struct iovec **kiov, struct iovec *siov,
+    size_t iov_cnt, size_t *iov_len)
+{
+	struct iovec *iovp;
+	int error, i;
+
+	if (iov_cnt >= UIO_MAXIOV)
+		return EMSGSIZE;
+	if (iov_cnt >= UIO_SMALLIOV) {
+		MALLOC(*kiov, struct iovec *, sizeof(struct iovec) * iov_cnt,
+		    M_IOV, M_WAITOK);
+	} else {
+		*kiov = siov;
+	}
+	error = copyin(uiov, *kiov, iov_cnt * sizeof(struct iovec));
+	if (error)
+		goto cleanup;
+	*iov_len = 0;
+	for (i = 0, iovp = *kiov; i < iov_cnt; i++, iovp++) {
+		*iov_len += iovp->iov_len;
+		if (iov_len < 0) {
+			error = EINVAL;
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	if (error)
+		iovec_free(kiov, siov);
+	return (error);
+}
Index: kern/syscalls.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/syscalls.c,v
retrieving revision 1.7
diff -u -u -r1.7 syscalls.c
--- kern/syscalls.c	12 Aug 2003 02:36:15 -0000	1.7
+++ kern/syscalls.c	7 Oct 2003 02:53:05 -0000
@@ -2,7 +2,7 @@
  * System call names.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/kern/syscalls.c,v 1.7 2003/08/12 02:36:15 dillon Exp $
+ * $DragonFly$
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -343,7 +343,7 @@
 	"sched_get_priority_min",			/* 333 = sched_get_priority_min */
 	"sched_rr_get_interval",			/* 334 = sched_rr_get_interval */
 	"utrace",			/* 335 = utrace */
-	"old.sendfile",		/* 336 = old sendfile */
+	"obs_freebsd4_sendfile",			/* 336 = obsolete freebsd4_sendfile */
 	"kldsym",			/* 337 = kldsym */
 	"jail",			/* 338 = jail */
 	"#339",			/* 339 = pioctl */
Index: kern/syscalls.master
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/syscalls.master,v
retrieving revision 1.2
diff -u -u -r1.2 syscalls.master
--- kern/syscalls.master	17 Jun 2003 04:28:41 -0000	1.2
+++ kern/syscalls.master	7 Oct 2003 02:51:54 -0000
@@ -474,8 +474,7 @@
 333     STD     POSIX   { int sched_get_priority_min (int policy); }
 334     STD     POSIX   { int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
 335	STD	BSD	{ int utrace(const void *addr, size_t len); }
-336	COMPAT	BSD	{ int sendfile(int fd, int s, off_t offset, size_t nbytes, \
-				struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
+336	OBSOL	NOHIDE	freebsd4_sendfile
 337	STD	BSD	{ int kldsym(int fileid, int cmd, void *data); }
 338	STD	BSD	{ int jail(struct jail *jail); }
 339	UNIMPL	BSD	pioctl
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.17
diff -u -u -r1.17 uipc_syscalls.c
--- kern/uipc_syscalls.c	3 Oct 2003 00:04:04 -0000	1.17
+++ kern/uipc_syscalls.c	7 Oct 2003 04:46:48 -0000
@@ -38,7 +38,6 @@
  * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.17 2003/10/03 00:04:04 daver Exp $
  */
 
-#include "opt_compat.h"
 #include "opt_ktrace.h"
 
 #include <sys/param.h>
@@ -73,15 +72,8 @@
 #include <vm/vm_extern.h>
 #include <sys/file2.h>
 
-#if defined(COMPAT_43)
-#include <emulation/43bsd/43bsd_socket.h>
-#endif /* COMPAT_43 */
-
 static void sf_buf_init(void *arg);
 SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL)
-
-static int do_sendfile(struct sendfile_args *uap, int compat);
-
 static SLIST_HEAD(, sf_buf) sf_freelist;
 static vm_offset_t sf_base;
 static struct sf_buf *sf_bufs;
@@ -90,9 +82,6 @@
 /*
  * System call interface to the socket abstraction.
  */
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-#define COMPAT_OLDSOCK
-#endif
 
 extern	struct fileops socketops;
 
@@ -100,7 +89,7 @@
  * socket_args(int domain, int type, int protocol)
  */
 int
-socket(struct socket_args *uap)
+kern_socket(int domain, int type, int protocol, int *res)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
@@ -116,7 +105,7 @@
 	if (error)
 		return (error);
 	fhold(fp);
-	error = socreate(uap->domain, &so, uap->type, uap->protocol, td);
+	error = socreate(domain, &so, type, protocol, td);
 	if (error) {
 		if (fdp->fd_ofiles[fd] == fp) {
 			fdp->fd_ofiles[fd] = NULL;
@@ -127,13 +116,23 @@
 		fp->f_flag = FREAD|FWRITE;
 		fp->f_ops = &socketops;
 		fp->f_type = DTYPE_SOCKET;
-		uap->sysmsg_result = fd;
+		*res = fd;
 	}
 	fdrop(fp, td);
 	return (error);
 }
 
 int
+socket(struct socket_args *uap)
+{
+	int error;
+
+	error = kern_socket(uap->domain, uap->type, uap->protocol,
+	    &uap->sysmsg_result);
+
+	return (error);
+}
+int
 kern_bind(int s, struct sockaddr *sa)
 {
 	struct thread *td = curthread;
@@ -615,10 +614,10 @@
 	struct thread *td = curthread;
 	struct msghdr msg;
 	struct uio auio;
-	struct iovec aiov[UIO_SMALLIOV], *iov = NULL, *iovp;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
 	struct sockaddr *sa = NULL;
 	struct mbuf *control = NULL;
-	int error, i;
+	int error;
 
 	error = copyin(uap->msg, (caddr_t)&msg, sizeof(msg));
 	if (error)
@@ -636,30 +635,13 @@
 	/*
 	 * Populate auio.
 	 */
-	if (msg.msg_iovlen >= UIO_MAXIOV) {
-		error =  EMSGSIZE;
-		goto cleanup;
-	}
-	if (msg.msg_iovlen >= UIO_SMALLIOV) {
-		MALLOC(iov, struct iovec *,
-		    sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
-	} else {
-		iov = aiov;
-	}
-	error = copyin(msg.msg_iov, iov, msg.msg_iovlen * sizeof(struct iovec));
+	error = iovec_copyin(msg.msg_iov, &iov, aiov, msg.msg_iovlen,
+	    &auio.uio_resid);
 	if (error)
 		goto cleanup;
 	auio.uio_iov = iov;
 	auio.uio_iovcnt = msg.msg_iovlen;
 	auio.uio_offset = 0;
-	auio.uio_resid = 0;
-	for (i = 0, iovp = auio.uio_iov; i < msg.msg_iovlen; i++, iovp++) {
-		auio.uio_resid += iovp->iov_len;
-		if (auio.uio_resid < 0) {
-			error = EINVAL;
-			goto cleanup;
-		}
-	}
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_rw = UIO_WRITE;
 	auio.uio_td = td;
@@ -693,8 +675,7 @@
 cleanup:
 	if (sa)
 		FREE(sa, M_SONAME);
-	if (iov != aiov)
-		FREE(iov, M_IOV);
+	iovec_free(&iov, aiov);
 	return (error);
 }
 
@@ -811,12 +792,12 @@
 	struct thread *td = curthread;
 	struct msghdr msg;
 	struct uio auio;
-	struct iovec aiov[UIO_SMALLIOV], *iov = NULL, *iovp;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
 	struct mbuf *m, *control;
 	struct sockaddr *sa = NULL;
 	caddr_t ctlbuf;
 	socklen_t *ufromlenp, *ucontrollenp;
-	int error, fromlen, controllen, len, i, flags, *uflagsp;
+	int error, fromlen, controllen, len, flags, *uflagsp;
 
 	/*
 	 * This copyin handles everything except the iovec.
@@ -840,28 +821,13 @@
 	/*
 	 * Populate auio.
 	 */
-	if (msg.msg_iovlen >= UIO_MAXIOV)
-		return (EMSGSIZE);
-	if (msg.msg_iovlen >= UIO_SMALLIOV) {
-		MALLOC(iov, struct iovec *,
-		    sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
-	} else {
-		iov = aiov;
-	}
-	error = copyin(msg.msg_iov, iov, msg.msg_iovlen * sizeof(struct iovec));
+	error = iovec_copyin(msg.msg_iov, &iov, aiov, msg.msg_iovlen,
+	    &auio.uio_resid);
 	if (error)
-		goto cleanup;
+		return (error);
 	auio.uio_iov = iov;
 	auio.uio_iovcnt = msg.msg_iovlen;
 	auio.uio_offset = 0;
-	auio.uio_resid = 0;
-	for (i = 0, iovp = auio.uio_iov; i < msg.msg_iovlen; i++, iovp++) {
-		auio.uio_resid += iovp->iov_len;
-		if (auio.uio_resid < 0) {
-			error = EINVAL;
-			goto cleanup;
-		}
-	}
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_rw = UIO_READ;
 	auio.uio_td = td;
@@ -919,8 +885,7 @@
 cleanup:
 	if (sa)
 		FREE(sa, M_SONAME);
-	if (iov != aiov)
-		FREE(iov, M_IOV);
+	iovec_free(&iov, aiov);
 	if (control)
 		m_freem(control);
 	return (error);
@@ -929,9 +894,8 @@
 /*
  * shutdown_args(int s, int how)
  */
-/* ARGSUSED */
 int
-shutdown(struct shutdown_args *uap)
+kern_shutdown(int s, int how)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
@@ -939,14 +903,24 @@
 	int error;
 
 	KKASSERT(p);
-	error = holdsock(p->p_fd, uap->s, &fp);
+	error = holdsock(p->p_fd, s, &fp);
 	if (error)
 		return (error);
-	error = soshutdown((struct socket *)fp->f_data, uap->how);
+	error = soshutdown((struct socket *)fp->f_data, how);
 	fdrop(fp, td);
 	return(error);
 }
 
+int
+shutdown(struct shutdown_args *uap)
+{
+	int error;
+
+	error = kern_shutdown(uap->s, uap->how);
+
+	return (error);
+}
+
 /*
  * If sopt->sopt_td == NULL, then sopt->sopt_val is treated as an
  * in kernel pointer instead of a userland pointer.  This allows us
@@ -1189,50 +1163,6 @@
 	return (error);
 }
 
-/*
- * sockargs() will be removed soon.  It is currently only called from the
- * emulation code.
- */
-int
-sockargs(mp, buf, buflen, type)
-	struct mbuf **mp;
-	caddr_t buf;
-	int buflen, type;
-{
-	struct sockaddr *sa;
-	struct mbuf *m;
-	int error;
-
-	if ((u_int)buflen > MLEN) {
-#ifdef COMPAT_OLDSOCK
-		if (type == MT_SONAME && (u_int)buflen <= 112)
-			buflen = MLEN;		/* unix domain compat. hack */
-		else
-#endif
-		return (EINVAL);
-	}
-	m = m_get(M_WAIT, type);
-	if (m == NULL)
-		return (ENOBUFS);
-	m->m_len = buflen;
-	error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
-	if (error)
-		(void) m_free(m);
-	else {
-		*mp = m;
-		if (type == MT_SONAME) {
-			sa = mtod(m, struct sockaddr *);
-
-#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
-			if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
-				sa->sa_family = sa->sa_len;
-#endif
-			sa->sa_len = buflen;
-		}
-	}
-	return (error);
-}
-
 int
 getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
 {
@@ -1249,7 +1179,11 @@
 	if (error) {
 		FREE(sa, M_SONAME);
 	} else {
-#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
+#if BYTE_ORDER != BIG_ENDIAN
+		/*
+		 * The bind(), connect(), and sendto() syscalls were not
+		 * versioned for COMPAT_43.  Thus, this check must stay.
+		 */
 		if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
 			sa->sa_family = sa->sa_len;
 #endif
@@ -1389,54 +1323,29 @@
  * specified by 's'. Send only 'nbytes' of the file or until EOF if
  * nbytes == 0. Optionally add a header and/or trailer to the socket
  * output. If specified, write the total number of bytes sent into *sbytes.
+ *
+ * In FreeBSD kern/uipc_syscalls.c,v 1.103, a bug was fixed that caused
+ * the headers to count against the remaining bytes to be sent from
+ * the file descriptor.  We may wish to implement a compatibility syscall
+ * in the future.
  */
 int
 sendfile(struct sendfile_args *uap)
 {
-	return (do_sendfile(uap, 0));
-}
-
-#ifdef COMPAT_43
-int
-osendfile(struct osendfile_args *uap)
-{
-	struct sendfile_args args;
-
-	args.fd = uap->fd;
-	args.s = uap->s;
-	args.offset = uap->offset;
-	args.nbytes = uap->nbytes;
-	args.hdtr = uap->hdtr;
-	args.sbytes = uap->sbytes;
-	args.flags = uap->flags;
-
-	return (do_sendfile(&args, 1));
-}
-#endif
-
-int
-do_sendfile(struct sendfile_args *uap, int compat)
-{
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
 	struct file *fp;
 	struct filedesc *fdp;
-	struct vnode *vp;
-	struct vm_object *obj;
-	struct socket *so;
-	struct mbuf *m;
-	struct sf_buf *sf;
-	struct vm_page *pg;
-	struct writev_args nuap;
+	struct vnode *vp = NULL;
 	struct sf_hdtr hdtr;
-	off_t off, xfsize, hdtr_size, sbytes = 0;
-	int error = 0, s;
+	struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
+	struct uio auio;
+	off_t hdtr_size = 0, sbytes;
+	int error, res;
 
 	KKASSERT(p);
 	fdp = p->p_fd;
 
-	vp = NULL;
-	hdtr_size = 0;
 	/*
 	 * Do argument checking. Must be a regular file in, stream
 	 * type and connected socket out, positive offset.
@@ -1452,12 +1361,99 @@
 	}
 	vp = (struct vnode *)fp->f_data;
 	vref(vp);
+	fdrop(fp, td);
+
+	/*
+	 * If specified, get the pointer to the sf_hdtr struct for
+	 * any headers/trailers.
+	 */
+	if (uap->hdtr) {
+		error = copyin(uap->hdtr, &hdtr, sizeof(hdtr));
+		if (error)
+			goto done;
+		/*
+		 * Send any headers.
+		 */
+		if (hdtr.headers) {
+			error = iovec_copyin(hdtr.headers, &iov, aiov,
+			    hdtr.hdr_cnt, &auio.uio_resid);
+			if (error)
+				goto done;
+			auio.uio_iov = iov;
+			auio.uio_iovcnt = hdtr.hdr_cnt;
+			auio.uio_offset = 0;
+			auio.uio_segflg = UIO_USERSPACE;
+			auio.uio_rw = UIO_WRITE;
+			auio.uio_td = td;
+
+			error = kern_sendmsg(uap->s, NULL, &auio, NULL, 0,
+			    &res);
+
+			iovec_free(&iov, aiov);
+			if (error)
+				goto done;
+			hdtr_size += res;
+		}
+	}
+
+	error = kern_sendfile(vp, uap->s, uap->offset, uap->nbytes,
+	    &sbytes, uap->flags);
+	if (error)
+		goto done;
+
+	/*
+	 * Send trailers. Wimp out and use writev(2).
+	 */
+	if (uap->hdtr != NULL && hdtr.trailers != NULL) {
+		error = iovec_copyin(hdtr.trailers, &iov, aiov,
+		    hdtr.trl_cnt, &auio.uio_resid);
+		if (error)
+			goto done;
+		auio.uio_iov = iov;
+		auio.uio_iovcnt = hdtr.trl_cnt;
+		auio.uio_offset = 0;
+		auio.uio_segflg = UIO_USERSPACE;
+		auio.uio_rw = UIO_WRITE;
+		auio.uio_td = td;
+
+		error = kern_sendmsg(uap->s, NULL, &auio, NULL, 0, &res);
+
+		iovec_free(&iov, aiov);
+		if (error)
+			goto done;
+		hdtr_size += res;
+	}
+
+done:
+	if (uap->sbytes != NULL) {
+		sbytes += hdtr_size;
+		copyout(&sbytes, uap->sbytes, sizeof(off_t));
+	}
+	if (vp)
+		vrele(vp);
+	return (error);
+}
+
+int
+kern_sendfile(struct vnode *vp, int s, off_t offset, size_t nbytes,
+    off_t *sbytes, int flags)
+{
+	struct thread *td = curthread;
+	struct proc *p = td->td_proc;
+	struct vm_object *obj;
+	struct socket *so;
+	struct file *fp;
+	struct mbuf *m;
+	struct sf_buf *sf;
+	struct vm_page *pg;
+	off_t off, xfsize;
+	int error = 0;
+
 	if (vp->v_type != VREG || VOP_GETVOBJECT(vp, &obj) != 0) {
 		error = EINVAL;
 		goto done;
 	}
-	fdrop(fp, td);
-	error = holdsock(p->p_fd, uap->s, &fp);
+	error = holdsock(p->p_fd, s, &fp);
 	if (error)
 		goto done;
 	so = (struct socket *)fp->f_data;
@@ -1469,36 +1465,12 @@
 		error = ENOTCONN;
 		goto done;
 	}
-	if (uap->offset < 0) {
+	if (offset < 0) {
 		error = EINVAL;
 		goto done;
 	}
 
-	/*
-	 * If specified, get the pointer to the sf_hdtr struct for
-	 * any headers/trailers.
-	 */
-	if (uap->hdtr != NULL) {
-		error = copyin(uap->hdtr, &hdtr, sizeof(hdtr));
-		if (error)
-			goto done;
-		/*
-		 * Send any headers. Wimp out and use writev(2).
-		 */
-		if (hdtr.headers != NULL) {
-			nuap.fd = uap->s;
-			nuap.iovp = hdtr.headers;
-			nuap.iovcnt = hdtr.hdr_cnt;
-			error = writev(&nuap);
-			if (error)
-				goto done;
-			if (compat)
-				sbytes += nuap.sysmsg_result;
-			else
-				hdtr_size += nuap.sysmsg_result;
-		}
-	}
-
+	*sbytes = 0;
 	/*
 	 * Protect against multiple writers to the socket.
 	 */
@@ -1510,7 +1482,7 @@
 	 * into an sf_buf, attach an mbuf header to the sf_buf, and queue
 	 * it on the socket.
 	 */
-	for (off = uap->offset; ; off += xfsize, sbytes += xfsize) {
+	for (off = offset; ; off += xfsize, *sbytes += xfsize) {
 		vm_pindex_t pindex;
 		vm_offset_t pgoff;
 
@@ -1526,8 +1498,8 @@
 		pgoff = (vm_offset_t)(off & PAGE_MASK);
 		if (PAGE_SIZE - pgoff < xfsize)
 			xfsize = PAGE_SIZE - pgoff;
-		if (uap->nbytes && xfsize > (uap->nbytes - sbytes))
-			xfsize = uap->nbytes - sbytes;
+		if (nbytes && xfsize > (nbytes - *sbytes))
+			xfsize = nbytes - *sbytes;
 		if (xfsize <= 0)
 			break;
 		/*
@@ -1727,30 +1699,7 @@
 	}
 	sbunlock(&so->so_snd);
 
-	/*
-	 * Send trailers. Wimp out and use writev(2).
-	 */
-	if (uap->hdtr != NULL && hdtr.trailers != NULL) {
-			nuap.fd = uap->s;
-			nuap.iovp = hdtr.trailers;
-			nuap.iovcnt = hdtr.trl_cnt;
-			error = writev(&nuap);
-			if (error)
-				goto done;
-			if (compat)
-				sbytes += nuap.sysmsg_result;
-			else
-				hdtr_size += nuap.sysmsg_result;
-	}
-
 done:
-	if (uap->sbytes != NULL) {
-		if (compat == 0)
-			sbytes += hdtr_size;
-		copyout(&sbytes, uap->sbytes, sizeof(off_t));
-	}
-	if (vp)
-		vrele(vp);
 	if (fp)
 		fdrop(fp, td);
 	return (error);
Index: sys/kern_syscall.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/kern_syscall.h,v
retrieving revision 1.4
diff -u -u -r1.4 kern_syscall.h
--- sys/kern_syscall.h	3 Oct 2003 00:04:04 -0000	1.4
+++ sys/kern_syscall.h	7 Oct 2003 04:17:11 -0000
@@ -33,8 +33,11 @@
 
 struct mbuf;
 struct msghdr;
+struct sf_hdtr;
 struct sockaddr;
+struct socket;
 struct sockopt;
+struct vnode;
 
 int kern_accept(int s, struct sockaddr **name, int *namelen, int *res);
 int kern_bind(int s, struct sockaddr *sa);
@@ -45,9 +48,13 @@
 int kern_getsockname(int s, struct sockaddr **name, int *namelen);
 int kern_recvmsg(int s, struct sockaddr **sa, struct uio *auio,
 	struct mbuf **control, int *flags, int *res);
+int kern_shutdown(int s, int how);
+int kern_sendfile(struct vnode *vp, int s, off_t offset, size_t nbytes,
+	off_t *sbytes, int flags);
 int kern_sendmsg(int s, struct sockaddr *sa, struct uio *auio,
 	struct mbuf *control, int flags, int *res);
 int kern_setsockopt(int s, struct sockopt *sopt);
+int kern_socket(int domain, int type, int protocol, int *res);
 int kern_socketpair(int domain, int type, int protocol, int *sockv);
 
 #endif /* !_SYS_KERN_SYSCALL_H_ */
Index: sys/socketvar.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/socketvar.h,v
retrieving revision 1.5
diff -u -u -r1.5 socketvar.h
--- sys/socketvar.h	24 Aug 2003 23:07:08 -0000	1.5
+++ sys/socketvar.h	3 Oct 2003 01:42:15 -0000
@@ -328,7 +328,6 @@
  */
 struct	sockaddr *dup_sockaddr (struct sockaddr *sa, int canwait);
 int	holdsock (struct filedesc *fdp, int fdes, struct file **fpp);
-int	sockargs (struct mbuf **mp, caddr_t buf, int buflen, int type);
 int	getsockaddr (struct sockaddr **namp, caddr_t uaddr, size_t len);
 void	sbappend (struct sockbuf *sb, struct mbuf *m);
 int	sbappendaddr (struct sockbuf *sb, struct sockaddr *asa,
Index: sys/syscall-hide.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/syscall-hide.h,v
retrieving revision 1.8
diff -u -u -r1.8 syscall-hide.h
--- sys/syscall-hide.h	20 Aug 2003 07:31:21 -0000	1.8
+++ sys/syscall-hide.h	7 Oct 2003 02:53:05 -0000
@@ -2,7 +2,7 @@
  * System call hiders.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/syscall-hide.h,v 1.8 2003/08/20 07:31:21 rob Exp $
+ * $DragonFly$
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -254,7 +254,6 @@
 HIDE_POSIX(sched_get_priority_min)
 HIDE_POSIX(sched_rr_get_interval)
 HIDE_BSD(utrace)
-HIDE_BSD(sendfile)
 HIDE_BSD(kldsym)
 HIDE_BSD(jail)
 HIDE_BSD(pioctl)
Index: sys/syscall.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/syscall.h,v
retrieving revision 1.8
diff -u -u -r1.8 syscall.h
--- sys/syscall.h	20 Aug 2003 07:31:21 -0000	1.8
+++ sys/syscall.h	7 Oct 2003 02:53:05 -0000
@@ -2,7 +2,7 @@
  * System call numbers.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/syscall.h,v 1.8 2003/08/20 07:31:21 rob Exp $
+ * $DragonFly$
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -260,7 +260,7 @@
 #define	SYS_sched_get_priority_min	333
 #define	SYS_sched_rr_get_interval	334
 #define	SYS_utrace	335
-				/* 336 is old sendfile */
+				/* 336 is obsolete freebsd4_sendfile */
 #define	SYS_kldsym	337
 #define	SYS_jail	338
 #define	SYS_sigprocmask	340
Index: sys/syscall.mk
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/syscall.mk,v
retrieving revision 1.8
diff -u -u -r1.8 syscall.mk
--- sys/syscall.mk	20 Aug 2003 07:31:21 -0000	1.8
+++ sys/syscall.mk	7 Oct 2003 02:53:05 -0000
@@ -1,6 +1,6 @@
 # DragonFly system call names.
 # DO NOT EDIT-- this file is automatically generated.
-# $DragonFly: src/sys/sys/syscall.mk,v 1.8 2003/08/20 07:31:21 rob Exp $
+# $DragonFly$
 # created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
 MIASM =  \
 	syscall.o \
Index: sys/sysproto.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/sysproto.h,v
retrieving revision 1.8
diff -u -u -r1.8 sysproto.h
--- sys/sysproto.h	20 Aug 2003 07:31:21 -0000	1.8
+++ sys/sysproto.h	7 Oct 2003 02:53:05 -0000
@@ -2,7 +2,7 @@
  * System call prototypes.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/sysproto.h,v 1.8 2003/08/20 07:31:21 rob Exp $
+ * $DragonFly$
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -2447,19 +2447,6 @@
 	u_int	count;	char count_[PAD_(u_int)];
 	long *	basep;	char basep_[PAD_(long *)];
 };
-struct	osendfile_args {
-#ifdef _KERNEL
-	union sysmsg sysmsg;
-#endif
-	union usrmsg usrmsg;
-	int	fd;	char fd_[PAD_(int)];
-	int	s;	char s_[PAD_(int)];
-	off_t	offset;	char offset_[PAD_(off_t)];
-	size_t	nbytes;	char nbytes_[PAD_(size_t)];
-	struct sf_hdtr *	hdtr;	char hdtr_[PAD_(struct sf_hdtr *)];
-	off_t *	sbytes;	char sbytes_[PAD_(off_t *)];
-	int	flags;	char flags_[PAD_(int)];
-};
 
 #ifdef _KERNEL
 
@@ -2500,7 +2487,6 @@
 int	oquota (struct oquota_args *);
 int	ogetsockname (struct getsockname_args *);
 int	ogetdirentries (struct ogetdirentries_args *);
-int	osendfile (struct osendfile_args *);
 
 #endif /* _KERNEL */
 
Index: sys/sysunion.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/sysunion.h,v
retrieving revision 1.5
diff -u -u -r1.5 sysunion.h
--- sys/sysunion.h	20 Aug 2003 07:31:21 -0000	1.5
+++ sys/sysunion.h	7 Oct 2003 02:53:05 -0000
@@ -2,7 +2,7 @@
  * Union of syscall args for messaging.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/sysunion.h,v 1.5 2003/08/20 07:31:21 rob Exp $
+ * $DragonFly$
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -308,9 +308,6 @@
 	struct	sched_get_priority_min_args sched_get_priority_min;
 	struct	sched_rr_get_interval_args sched_rr_get_interval;
 	struct	utrace_args utrace;
-#ifdef COMPAT_43
-	struct	osendfile_args osendfile;
-#endif
 	struct	kldsym_args kldsym;
 	struct	jail_args jail;
 	struct	sigprocmask_args sigprocmask;
Index: sys/uio.h
===================================================================
RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/uio.h,v
retrieving revision 1.5
diff -u -u -r1.5 uio.h
--- sys/uio.h	2 Oct 2003 19:21:06 -0000	1.5
+++ sys/uio.h	7 Oct 2003 02:41:03 -0000
@@ -38,6 +38,8 @@
 #ifndef _SYS_UIO_H_
 #define	_SYS_UIO_H_
 
+#include <sys/malloc.h>		/* Needed to inline iovec_free(). */
+
 /*
  * XXX
  * iov_base should be a void *.
@@ -86,6 +88,17 @@
 int 	uiomove_frombuf (void *buf, int buflen, struct uio *uio);
 int	uiomoveco (caddr_t, int, struct uio *, struct vm_object *);
 int	uioread (int, struct uio *, struct vm_object *, int *);
+int	iovec_copyin(struct iovec *, struct iovec **, struct iovec *,
+	size_t, size_t *);
+
+static __inline void
+iovec_free(struct iovec **kiov, struct iovec *siov)
+{
+	if (*kiov != siov) {
+		FREE(*kiov, M_IOV);
+		*kiov = NULL;
+	}
+}
 
 #else /* !_KERNEL */
 

