Date: Thu, 16 Jun 2011 07:16:03 +0000 (UTC) From: Attilio Rao <attilio@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r223140 - in projects/largeSMP: bin/sh contrib/top etc/periodic/daily lib/libc/gen lib/libc/net lib/libstand libexec/tftpd release share/mk sys/boot/forth sys/conf sys/dev/sound/pci/hda... Message-ID: <201106160716.p5G7G3xR017185@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: attilio Date: Thu Jun 16 07:16:02 2011 New Revision: 223140 URL: http://svn.freebsd.org/changeset/base/223140 Log: MFC Added: projects/largeSMP/tools/regression/bin/sh/builtins/case8.0 - copied unchanged from r223138, head/tools/regression/bin/sh/builtins/case8.0 Modified: projects/largeSMP/bin/sh/expand.c projects/largeSMP/bin/sh/sh.1 projects/largeSMP/etc/periodic/daily/800.scrub-zfs projects/largeSMP/lib/libc/gen/sysconf.c projects/largeSMP/lib/libc/net/sctp_sys_calls.c projects/largeSMP/lib/libstand/Makefile projects/largeSMP/lib/libstand/net.c projects/largeSMP/lib/libstand/tftp.c projects/largeSMP/libexec/tftpd/tftpd.8 projects/largeSMP/release/Makefile projects/largeSMP/sys/boot/forth/loader.rc projects/largeSMP/sys/conf/Makefile.arm projects/largeSMP/sys/dev/sound/pci/hda/hdac.c projects/largeSMP/sys/netinet/sctp.h projects/largeSMP/sys/netinet/sctp_auth.c projects/largeSMP/sys/netinet/sctp_indata.c projects/largeSMP/sys/netinet/sctp_output.c projects/largeSMP/sys/netinet/sctp_pcb.c projects/largeSMP/sys/netinet/sctp_structs.h projects/largeSMP/sys/netinet/sctp_uio.h projects/largeSMP/sys/netinet/sctp_usrreq.c projects/largeSMP/sys/netinet/sctp_var.h projects/largeSMP/sys/netinet/sctputil.c projects/largeSMP/sys/sparc64/include/smp.h projects/largeSMP/sys/ufs/ffs/ffs_alloc.c projects/largeSMP/sys/ufs/ffs/ffs_balloc.c projects/largeSMP/sys/ufs/ffs/ffs_extern.h projects/largeSMP/sys/ufs/ffs/ffs_inode.c projects/largeSMP/sys/ufs/ffs/ffs_snapshot.c projects/largeSMP/sys/ufs/ffs/ffs_softdep.c projects/largeSMP/sys/ufs/ffs/softdep.h projects/largeSMP/usr.bin/tftp/main.c projects/largeSMP/usr.bin/tftp/tftp.1 projects/largeSMP/usr.sbin/pw/pw_user.c Directory Properties: projects/largeSMP/ (props changed) projects/largeSMP/cddl/contrib/opensolaris/ (props changed) projects/largeSMP/contrib/bind9/ (props changed) projects/largeSMP/contrib/binutils/ (props changed) projects/largeSMP/contrib/bzip2/ (props changed) projects/largeSMP/contrib/compiler-rt/ (props changed) projects/largeSMP/contrib/dialog/ (props changed) projects/largeSMP/contrib/ee/ (props changed) projects/largeSMP/contrib/expat/ (props changed) projects/largeSMP/contrib/file/ (props changed) projects/largeSMP/contrib/gcc/ (props changed) projects/largeSMP/contrib/gdb/ (props changed) projects/largeSMP/contrib/gdtoa/ (props changed) projects/largeSMP/contrib/gnu-sort/ (props changed) projects/largeSMP/contrib/groff/ (props changed) projects/largeSMP/contrib/less/ (props changed) projects/largeSMP/contrib/libpcap/ (props changed) projects/largeSMP/contrib/libstdc++/ (props changed) projects/largeSMP/contrib/llvm/ (props changed) projects/largeSMP/contrib/llvm/tools/clang/ (props changed) projects/largeSMP/contrib/ncurses/ (props changed) projects/largeSMP/contrib/netcat/ (props changed) projects/largeSMP/contrib/ntp/ (props changed) projects/largeSMP/contrib/one-true-awk/ (props changed) projects/largeSMP/contrib/openbsm/ (props changed) projects/largeSMP/contrib/openpam/ (props changed) projects/largeSMP/contrib/pf/ (props changed) projects/largeSMP/contrib/sendmail/ (props changed) projects/largeSMP/contrib/tcpdump/ (props changed) projects/largeSMP/contrib/tcsh/ (props changed) projects/largeSMP/contrib/top/ (props changed) projects/largeSMP/contrib/top/install-sh (props changed) projects/largeSMP/contrib/tzcode/stdtime/ (props changed) projects/largeSMP/contrib/tzcode/zic/ (props changed) projects/largeSMP/contrib/tzdata/ (props changed) projects/largeSMP/contrib/wpa/ (props changed) projects/largeSMP/contrib/xz/ (props changed) projects/largeSMP/crypto/openssh/ (props changed) projects/largeSMP/crypto/openssl/ (props changed) projects/largeSMP/gnu/lib/ (props changed) projects/largeSMP/gnu/usr.bin/binutils/ (props changed) projects/largeSMP/gnu/usr.bin/cc/cc_tools/ (props changed) projects/largeSMP/gnu/usr.bin/gdb/ (props changed) projects/largeSMP/lib/libc/ (props changed) projects/largeSMP/lib/libc/stdtime/ (props changed) projects/largeSMP/lib/libutil/ (props changed) projects/largeSMP/lib/libz/ (props changed) projects/largeSMP/sbin/ (props changed) projects/largeSMP/sbin/ipfw/ (props changed) projects/largeSMP/share/mk/bsd.arch.inc.mk (props changed) projects/largeSMP/share/zoneinfo/ (props changed) projects/largeSMP/sys/ (props changed) projects/largeSMP/sys/amd64/include/xen/ (props changed) projects/largeSMP/sys/boot/ (props changed) projects/largeSMP/sys/boot/i386/efi/ (props changed) projects/largeSMP/sys/boot/ia64/efi/ (props changed) projects/largeSMP/sys/boot/ia64/ski/ (props changed) projects/largeSMP/sys/boot/powerpc/boot1.chrp/ (props changed) projects/largeSMP/sys/boot/powerpc/ofw/ (props changed) projects/largeSMP/sys/cddl/contrib/opensolaris/ (props changed) projects/largeSMP/sys/conf/ (props changed) projects/largeSMP/sys/contrib/dev/acpica/ (props changed) projects/largeSMP/sys/contrib/octeon-sdk/ (props changed) projects/largeSMP/sys/contrib/pf/ (props changed) projects/largeSMP/sys/contrib/x86emu/ (props changed) projects/largeSMP/usr.bin/calendar/ (props changed) projects/largeSMP/usr.bin/csup/ (props changed) projects/largeSMP/usr.bin/procstat/ (props changed) projects/largeSMP/usr.sbin/ndiscvt/ (props changed) projects/largeSMP/usr.sbin/zic/ (props changed) Modified: projects/largeSMP/bin/sh/expand.c ============================================================================== --- projects/largeSMP/bin/sh/expand.c Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/bin/sh/expand.c Thu Jun 16 07:16:02 2011 (r223140) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> #include <wchar.h> +#include <wctype.h> /* * Routines to expand arguments to commands. We have to deal with @@ -1401,13 +1402,43 @@ get_wc(const char **p) /* + * See if a character matches a character class, starting at the first colon + * of "[:class:]". + * If a valid character class is recognized, a pointer to the next character + * after the final closing bracket is stored into *end, otherwise a null + * pointer is stored into *end. + */ +static int +match_charclass(const char *p, wchar_t chr, const char **end) +{ + char name[20]; + const char *nameend; + wctype_t cclass; + + *end = NULL; + p++; + nameend = strstr(p, ":]"); + if (nameend == NULL || nameend - p >= sizeof(name) || nameend == p) + return 0; + memcpy(name, p, nameend - p); + name[nameend - p] = '\0'; + *end = nameend + 2; + cclass = wctype(name); + /* An unknown class matches nothing but is valid nevertheless. */ + if (cclass == 0) + return 0; + return iswctype(chr, cclass); +} + + +/* * Returns true if the pattern matches the string. */ int patmatch(const char *pattern, const char *string, int squoted) { - const char *p, *q; + const char *p, *q, *end; char c; wchar_t wc, wc2; @@ -1495,6 +1526,11 @@ patmatch(const char *pattern, const char do { if (c == CTLQUOTEMARK) continue; + if (c == '[' && *p == ':') { + found |= match_charclass(p, chr, &end); + if (end != NULL) + p = end; + } if (c == CTLESC) c = *p++; if (localeisutf8 && c & 0x80) { Modified: projects/largeSMP/bin/sh/sh.1 ============================================================================== --- projects/largeSMP/bin/sh/sh.1 Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/bin/sh/sh.1 Thu Jun 16 07:16:02 2011 (r223140) @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd June 12, 2011 +.Dd June 15, 2011 .Dt SH 1 .Os .Sh NAME @@ -1648,6 +1648,15 @@ matches a rather than introducing a character class. A character class matches any of the characters between the square brackets. A range of characters may be specified using a minus sign. +A named class of characters (see +.Xr wctype 3 ) +may be specified by surrounding the name with +.Ql \&[: +and +.Ql :\&] . +For example, +.Ql \&[\&[:alpha:\&]\&] +is a shell pattern that matches a single letter. The character class may be complemented by making an exclamation point .Pq Ql !\& the first character of the character class. @@ -2572,6 +2581,7 @@ will return the argument. .Xr execve 2 , .Xr getrlimit 2 , .Xr umask 2 , +.Xr wctype 3 , .Xr editrc 5 .Sh HISTORY A Modified: projects/largeSMP/etc/periodic/daily/800.scrub-zfs ============================================================================== --- projects/largeSMP/etc/periodic/daily/800.scrub-zfs Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/etc/periodic/daily/800.scrub-zfs Thu Jun 16 07:16:02 2011 (r223140) @@ -46,7 +46,7 @@ case "$daily_scrub_zfs_enable" in esac # determine how many days shall be between scrubs - eval _pool_threshold=\${daily_scrub_zfs_$(echo "${pool}"|tr -s "-" "_"|tr -s "." "_"|tr -s ":" "_")_threshold} + eval _pool_threshold=\${daily_scrub_zfs_$(echo "${pool}"|tr ".:-" "_")_threshold} if [ -z "${_pool_threshold}" ];then _pool_threshold=${daily_scrub_zfs_default_threshold} fi Modified: projects/largeSMP/lib/libc/gen/sysconf.c ============================================================================== --- projects/largeSMP/lib/libc/gen/sysconf.c Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/lib/libc/gen/sysconf.c Thu Jun 16 07:16:02 2011 (r223140) @@ -599,11 +599,11 @@ yesno: #ifdef _SC_CPUSET_SIZE case _SC_CPUSET_SIZE: - len = sizeof(lvalue); - if (sysctlbyname("kern.sched.cpusetsize", &lvalue, &len, NULL, + len = sizeof(value); + if (sysctlbyname("kern.sched.cpusetsize", &value, &len, NULL, 0) == -1) return (-1); - return (lvalue); + return ((long)value); #endif default: Modified: projects/largeSMP/lib/libc/net/sctp_sys_calls.c ============================================================================== --- projects/largeSMP/lib/libc/net/sctp_sys_calls.c Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/lib/libc/net/sctp_sys_calls.c Thu Jun 16 07:16:02 2011 (r223140) @@ -141,7 +141,7 @@ in6_sin6_2_sin(struct sockaddr_in *sin, int sctp_getaddrlen(sa_family_t family) { - int error, sd; + int ret, sd; socklen_t siz; struct sctp_assoc_value av; @@ -151,13 +151,15 @@ sctp_getaddrlen(sa_family_t family) sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); #elif defined(AF_INET6) sd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); +#else + sd = -1; #endif if (sd == -1) { return (-1); } - error = getsockopt(sd, IPPROTO_SCTP, SCTP_GET_ADDR_LEN, &av, &siz); + ret = getsockopt(sd, IPPROTO_SCTP, SCTP_GET_ADDR_LEN, &av, &siz); close(sd); - if (error == 0) { + if (ret == 0) { return ((int)av.assoc_value); } else { return (-1); @@ -402,6 +404,9 @@ sctp_opt_info(int sd, sctp_assoc_t id, i case SCTP_TIMEOUTS: ((struct sctp_timeouts *)arg)->stimo_assoc_id = id; break; + case SCTP_EVENT: + ((struct sctp_event *)arg)->se_assoc_id = id; + break; default: break; } @@ -919,32 +924,259 @@ sctp_recvmsg(int s, #endif } +ssize_t +sctp_recvv(int sd, + const struct iovec *iov, + int iovlen, + struct sockaddr *from, + socklen_t * fromlen, + void *info, + socklen_t * infolen, + unsigned int *infotype, + int *flags) +{ + char ctlbuf[SCTP_CONTROL_VEC_SIZE_RCV]; + struct msghdr msg; + struct cmsghdr *cmsg; + ssize_t n; + struct sctp_rcvinfo *rcvinfo; + struct sctp_nxtinfo *nxtinfo; -#if defined(HAVE_SCTP_PEELOFF_SOCKOPT) -#include <netinet/sctp_peeloff.h> + if (infotype) { + *infotype = SCTP_RECVV_NOINFO; + } + msg.msg_name = from; + if (fromlen == NULL) { + msg.msg_namelen = 0; + } else { + msg.msg_namelen = *fromlen; + } + msg.msg_iov = (struct iovec *)iov; + msg.msg_iovlen = iovlen; + msg.msg_control = ctlbuf; + msg.msg_controllen = sizeof(ctlbuf); + errno = 0; + n = recvmsg(sd, &msg, *flags); + *flags = msg.msg_flags; + if ((n > 0) && + (msg.msg_controllen > 0) && + (infotype != NULL) && + (infolen != NULL) && + (*infolen > 0)) { + rcvinfo = NULL; + nxtinfo = NULL; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != IPPROTO_SCTP) { + continue; + } + if (cmsg->cmsg_type == SCTP_RCVINFO) { + rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); + } + if (cmsg->cmsg_type == SCTP_NXTINFO) { + nxtinfo = (struct sctp_nxtinfo *)CMSG_DATA(cmsg); + } + if (rcvinfo && nxtinfo) { + break; + } + } + if (rcvinfo) { + if (nxtinfo) { + if (*infolen >= sizeof(struct sctp_recvv_rn)) { + struct sctp_recvv_rn *rn_info; + + rn_info = (struct sctp_recvv_rn *)info; + rn_info->recvv_rcvinfo = *rcvinfo; + rn_info->recvv_nxtinfo = *nxtinfo; + *infolen = (socklen_t) sizeof(struct sctp_recvv_rn); + *infotype = SCTP_RECVV_RN; + } + } else { + if (*infolen >= sizeof(struct sctp_rcvinfo)) { + memcpy(info, rcvinfo, sizeof(struct sctp_rcvinfo)); + *infolen = (socklen_t) sizeof(struct sctp_rcvinfo); + *infotype = SCTP_RECVV_RCVINFO; + } + } + } else if (nxtinfo) { + if (*infolen >= sizeof(struct sctp_rcvinfo)) { + memcpy(info, nxtinfo, sizeof(struct sctp_nxtinfo)); + *infolen = (socklen_t) sizeof(struct sctp_nxtinfo); + *infotype = SCTP_RECVV_NXTINFO; + } + } + } + return (n); +} -int -sctp_peeloff(int sd, sctp_assoc_t assoc_id) +ssize_t +sctp_sendv(int sd, + const struct iovec *iov, int iovcnt, + struct sockaddr *addrs, int addrcnt, + void *info, socklen_t infolen, unsigned int infotype, + int flags) { - struct sctp_peeloff_opt peeloff; - int result; - socklen_t optlen; - - /* set in the socket option params */ - memset(&peeloff, 0, sizeof(peeloff)); - peeloff.s = sd; - peeloff.assoc_id = assoc_id; - optlen = sizeof(peeloff); - result = getsockopt(sd, IPPROTO_SCTP, SCTP_PEELOFF, (void *)&peeloff, &optlen); + ssize_t ret; + int i; + size_t addr_len; + struct sctp_sendv_spa *spa_info; + struct msghdr msg; + struct cmsghdr *cmsg; + char *cmsgbuf; + struct sockaddr *addr; + struct sockaddr_in *addr_in; + struct sockaddr_in6 *addr_in6; - if (result < 0) { + if ((addrcnt < 0) || (iovcnt < 0)) { + errno = EINVAL; + return (-1); + } + cmsgbuf = malloc(CMSG_SPACE(sizeof(struct sctp_sndinfo)) + + CMSG_SPACE(sizeof(struct sctp_prinfo)) + + CMSG_SPACE(sizeof(struct sctp_authinfo)) + + addrcnt * CMSG_SPACE(sizeof(struct in6_addr))); + if (cmsgbuf == NULL) { + errno = ENOBUFS; return (-1); + } + msg.msg_control = cmsgbuf; + msg.msg_controllen = 0; + cmsg = (struct cmsghdr *)cmsgbuf; + switch (infotype) { + case SCTP_SENDV_SNDINFO: + if (infolen < sizeof(struct sctp_sndinfo)) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); + memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_sndinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo))); + break; + case SCTP_SENDV_PRINFO: + if (infolen < sizeof(struct sctp_prinfo)) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_PRINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); + memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_prinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo))); + break; + case SCTP_SENDV_AUTHINFO: + if (infolen < sizeof(struct sctp_authinfo)) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_AUTHINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_authinfo)); + memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_authinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_authinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo))); + break; + case SCTP_SENDV_SPA: + if (infolen < sizeof(struct sctp_sendv_spa)) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + spa_info = (struct sctp_sendv_spa *)info; + if (spa_info->sendv_flags & SCTP_SEND_SNDINFO_VALID) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); + memcpy(CMSG_DATA(cmsg), &spa_info->sendv_sndinfo, sizeof(struct sctp_sndinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo))); + } + if (spa_info->sendv_flags & SCTP_SEND_PRINFO_VALID) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_PRINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); + memcpy(CMSG_DATA(cmsg), &spa_info->sendv_prinfo, sizeof(struct sctp_prinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo))); + } + if (spa_info->sendv_flags & SCTP_SEND_AUTHINFO_VALID) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_AUTHINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_authinfo)); + memcpy(CMSG_DATA(cmsg), &spa_info->sendv_authinfo, sizeof(struct sctp_authinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_authinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo))); + } + break; + default: + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + addr = addrs; + if (addrcnt == 1) { + msg.msg_name = addr; + switch (addr->sa_family) { + case AF_INET: + msg.msg_namelen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + msg.msg_namelen = sizeof(struct sockaddr_in6); + break; + default: + free(cmsgbuf); + errno = EINVAL; + return (-1); + } } else { - return (peeloff.new_sd); + msg.msg_name = NULL; + msg.msg_namelen = 0; + for (i = 0; i < addrcnt; i++) { + switch (addr->sa_family) { + case AF_INET: + addr_len = sizeof(struct sockaddr_in); + addr_in = (struct sockaddr_in *)addr; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_DSTADDRV4; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + memcpy(CMSG_DATA(cmsg), &addr_in->sin_addr, sizeof(struct in_addr)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct in_addr)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in_addr))); + break; + case AF_INET6: + addr_len = sizeof(struct sockaddr_in6); + addr_in6 = (struct sockaddr_in6 *)addr; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_DSTADDRV6; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_addr)); + memcpy(CMSG_DATA(cmsg), &addr_in6->sin6_addr, sizeof(struct in6_addr)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct in6_addr)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in6_addr))); + break; + default: + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + addr = (struct sockaddr *)((caddr_t)addr + addr_len); + } } + if (msg.msg_controllen == 0) { + msg.msg_control = NULL; + } + msg.msg_iov = (struct iovec *)iov; + msg.msg_iovlen = iovcnt; + msg.msg_flags = 0; + ret = sendmsg(sd, &msg, flags); + free(cmsgbuf); + return (ret); } -#endif #if !defined(SYS_sctp_peeloff) && !defined(HAVE_SCTP_PEELOFF_SOCKOPT) Modified: projects/largeSMP/lib/libstand/Makefile ============================================================================== --- projects/largeSMP/lib/libstand/Makefile Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/lib/libstand/Makefile Thu Jun 16 07:16:02 2011 (r223140) @@ -15,7 +15,7 @@ NO_PIC= INCS= stand.h MAN= libstand.3 -WARNS?= 0 +WARNS?= 2 CFLAGS+= -ffreestanding -Wformat CFLAGS+= -I${.CURDIR} Modified: projects/largeSMP/lib/libstand/net.c ============================================================================== --- projects/largeSMP/lib/libstand/net.c Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/lib/libstand/net.c Thu Jun 16 07:16:02 2011 (r223140) @@ -100,7 +100,7 @@ sendrecv(struct iodesc *d, cc, ssize); tleft = tmo; - tmo <<= 1; + tmo += MINTMO; if (tmo > MAXTMO) tmo = MAXTMO; Modified: projects/largeSMP/lib/libstand/tftp.c ============================================================================== --- projects/largeSMP/lib/libstand/tftp.c Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/lib/libstand/tftp.c Thu Jun 16 07:16:02 2011 (r223140) @@ -60,12 +60,21 @@ __FBSDID("$FreeBSD$"); #include "tftp.h" +struct tftp_handle; + static int tftp_open(const char *path, struct open_file *f); static int tftp_close(struct open_file *f); +static void tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len); static int tftp_read(struct open_file *f, void *buf, size_t size, size_t *resid); static int tftp_write(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t tftp_seek(struct open_file *f, off_t offset, int where); +static int tftp_set_blksize(struct tftp_handle *h, const char *str); static int tftp_stat(struct open_file *f, struct stat *sb); +static ssize_t sendrecv_tftp(struct tftp_handle *h, + ssize_t (*sproc)(struct iodesc *, void *, size_t), + void *sbuf, size_t ssize, + ssize_t (*rproc)(struct tftp_handle *h, void *, ssize_t, time_t, unsigned short *), + void *rbuf, size_t rsize, unsigned short *rtype); struct fs_ops tftp_fsops = { "tftp", @@ -81,8 +90,20 @@ struct fs_ops tftp_fsops = { extern struct in_addr servip; static int tftpport = 2000; +static int is_open = 0; -#define RSPACE 520 /* max data packet, rounded up */ +/* + * The legacy TFTP_BLKSIZE value was 512. + * TFTP_REQUESTED_BLKSIZE of 1428 is (Ethernet MTU, less the TFTP, UDP and + * IP header lengths). + */ +#define TFTP_REQUESTED_BLKSIZE 1428 + +/* + * Choose a blksize big enough so we can test with Ethernet + * Jumbo frames in the future. + */ +#define TFTP_MAX_BLKSIZE 9008 struct tftp_handle { struct iodesc *iodesc; @@ -91,10 +112,12 @@ struct tftp_handle { int validsize; int off; char *path; /* saved for re-requests */ + unsigned int tftp_blksize; + unsigned long tftp_tsize; struct { u_char header[HEADER_SIZE]; struct tftphdr t; - u_char space[RSPACE]; + u_char space[TFTP_MAX_BLKSIZE]; } __packed __aligned(4) lastdata; }; @@ -110,8 +133,10 @@ static const int tftperrors[8] = { }; static ssize_t -recvtftp(struct iodesc *d, void *pkt, ssize_t len, time_t tleft) +recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft, + unsigned short *rtype) { + struct iodesc *d = h->iodesc; struct tftphdr *t; errno = 0; @@ -122,6 +147,7 @@ recvtftp(struct iodesc *d, void *pkt, ss return (-1); t = (struct tftphdr *) pkt; + *rtype = ntohs(t->th_opcode); switch (ntohs(t->th_opcode)) { case DATA: { int got; @@ -154,6 +180,18 @@ recvtftp(struct iodesc *d, void *pkt, ss errno = tftperrors[ntohs(t->th_code)]; } return (-1); + case OACK: { + struct udphdr *uh; + int tftp_oack_len = len - sizeof(t->th_opcode); + tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len); + /* + * Remember which port this OACK came from, + * because we need to send the ACK back to it. + */ + uh = (struct udphdr *) pkt - 1; + d->destport = uh->uh_sport; + return (0); + } default: #ifdef TFTP_DEBUG printf("tftp type %d not handled\n", ntohs(t->th_opcode)); @@ -175,14 +213,35 @@ tftp_makereq(struct tftp_handle *h) int l; ssize_t res; struct tftphdr *t; + char *tftp_blksize = NULL; + int blksize_l; + unsigned short rtype = 0; + + /* + * Allow overriding default TFTP block size by setting + * a tftp.blksize environment variable. + */ + if ((tftp_blksize = getenv("tftp.blksize")) != NULL) { + tftp_set_blksize(h, tftp_blksize); + } wbuf.t.th_opcode = htons((u_short) RRQ); wtail = wbuf.t.th_stuff; l = strlen(h->path); + if (l > FNAME_SIZE) + return (ENAMETOOLONG); bcopy(h->path, wtail, l + 1); wtail += l + 1; bcopy("octet", wtail, 6); wtail += 6; + bcopy("blksize", wtail, 8); + wtail += 8; + blksize_l = sprintf(wtail, "%d", h->tftp_blksize); + wtail += blksize_l + 1; + bcopy("tsize", wtail, 6); + wtail += 6; + bcopy("0", wtail, 2); + wtail += 2; t = &h->lastdata.t; @@ -191,18 +250,33 @@ tftp_makereq(struct tftp_handle *h) h->iodesc->destport = htons(IPPORT_TFTP); h->iodesc->xid = 1; /* expected block */ - res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - recvtftp, t, sizeof(*t) + RSPACE); + res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, + &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype); - if (res == -1) - return (errno); + if (rtype == OACK) { + wbuf.t.th_opcode = htons((u_short)ACK); + wtail = (char *) &wbuf.t.th_block; + wbuf.t.th_block = htons(0); + wtail += 2; + rtype = 0; + res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, + &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype); + } + + switch (rtype) { + case DATA: { + h->currblock = 1; + h->validsize = res; + h->islastblock = 0; + if (res < h->tftp_blksize) + h->islastblock = 1; /* very short file */ + return (0); + } + case ERROR: + default: + return (errno); + } - h->currblock = 1; - h->validsize = res; - h->islastblock = 0; - if (res < SEGSIZE) - h->islastblock = 1; /* very short file */ - return (0); } /* ack block, expect next */ @@ -216,7 +290,7 @@ tftp_getnextblock(struct tftp_handle *h) char *wtail; int res; struct tftphdr *t; - + unsigned short rtype = 0; wbuf.t.th_opcode = htons((u_short) ACK); wtail = (char *) &wbuf.t.th_block; wbuf.t.th_block = htons((u_short) h->currblock); @@ -226,16 +300,23 @@ tftp_getnextblock(struct tftp_handle *h) h->iodesc->xid = h->currblock + 1; /* expected block */ - res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - recvtftp, t, sizeof(*t) + RSPACE); + res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, + &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype); if (res == -1) /* 0 is OK! */ return (errno); h->currblock++; h->validsize = res; - if (res < SEGSIZE) + if (res < h->tftp_blksize) h->islastblock = 1; /* EOF */ + + if (h->islastblock == 1) { + /* Send an ACK for the last block */ + wbuf.t.th_block = htons((u_short) h->currblock); + sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); + } + return (0); } @@ -251,10 +332,15 @@ tftp_open(const char *path, struct open_ return (EINVAL); #endif + if (is_open) + return (EBUSY); + tftpfile = (struct tftp_handle *) malloc(sizeof(*tftpfile)); if (!tftpfile) return (ENOMEM); + memset(tftpfile, 0, sizeof(*tftpfile)); + tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE; tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata)); if (io == NULL) return (EINVAL); @@ -275,6 +361,7 @@ tftp_open(const char *path, struct open_ return (res); } f->f_fsdata = (void *) tftpfile; + is_open = 1; return (0); } @@ -292,7 +379,7 @@ tftp_read(struct open_file *f, void *add if (!(tc++ % 16)) twiddle(); - needblock = tftpfile->off / SEGSIZE + 1; + needblock = tftpfile->off / tftpfile->tftp_blksize + 1; if (tftpfile->currblock > needblock) /* seek backwards */ tftp_makereq(tftpfile); /* no error check, it worked @@ -315,7 +402,7 @@ tftp_read(struct open_file *f, void *add if (tftpfile->currblock == needblock) { int offinblock, inbuffer; - offinblock = tftpfile->off % SEGSIZE; + offinblock = tftpfile->off % tftpfile->tftp_blksize; inbuffer = tftpfile->validsize - offinblock; if (inbuffer < 0) { @@ -361,18 +448,19 @@ tftp_close(struct open_file *f) free(tftpfile->path); free(tftpfile); } + is_open = 0; return (0); } static int tftp_write(struct open_file *f __unused, void *start __unused, size_t size __unused, - size_t *resid /* out */ __unused) + size_t *resid __unused /* out */) { return (EROFS); } static int -tftp_stat(struct open_file *f, struct stat *sb) +tftp_stat(struct open_file *f, struct stat *sb) { struct tftp_handle *tftpfile; tftpfile = (struct tftp_handle *) f->f_fsdata; @@ -404,3 +492,166 @@ tftp_seek(struct open_file *f, off_t off } return (tftpfile->off); } + +static ssize_t +sendrecv_tftp(struct tftp_handle *h, + ssize_t (*sproc)(struct iodesc *, void *, size_t), + void *sbuf, size_t ssize, + ssize_t (*rproc)(struct tftp_handle *, void *, ssize_t, time_t, unsigned short *), + void *rbuf, size_t rsize, unsigned short *rtype) +{ + struct iodesc *d = h->iodesc; + ssize_t cc; + time_t t, t1, tleft; + +#ifdef TFTP_DEBUG + if (debug) + printf("sendrecv: called\n"); +#endif + + tleft = MINTMO; + t = t1 = getsecs(); + for (;;) { + if ((getsecs() - t) > MAXTMO) { + errno = ETIMEDOUT; + return -1; + } + + cc = (*sproc)(d, sbuf, ssize); + if (cc != -1 && cc < ssize) + panic("sendrecv: short write! (%zd < %zu)", + cc, ssize); + + if (cc == -1) { + /* Error on transmit; wait before retrying */ + while ((getsecs() - t1) < tleft); + continue; + } + +recvnext: + /* Try to get a packet and process it. */ + cc = (*rproc)(h, rbuf, rsize, tleft, rtype); + /* Return on data, EOF or real error. */ + if (cc != -1 || errno != 0) + return (cc); + if ((getsecs() - t1) < tleft) { + goto recvnext; + } + + /* Timed out or didn't get the packet we're waiting for */ + tleft += MINTMO; + if (tleft > (2 * MINTMO)) { + tleft = (2 * MINTMO); + } + t1 = getsecs(); + } +} + +static int +tftp_set_blksize(struct tftp_handle *h, const char *str) +{ + char *endptr; + int new_blksize; + int ret = 0; + + if (h == NULL || str == NULL) + return (ret); + + new_blksize = + (unsigned int)strtol(str, &endptr, 0); + + /* + * Only accept blksize value if it is numeric. + * RFC2348 specifies that acceptable valuesare 8-65464 + * 8-65464 . Let's choose a limit less than MAXRSPACE + */ + if (*endptr == '\0' && new_blksize >= 8 + && new_blksize <= TFTP_MAX_BLKSIZE) { + h->tftp_blksize = new_blksize; + ret = 1; + } + + return (ret); +} + +/* + * In RFC2347, the TFTP Option Acknowledgement package (OACK) + * is used to acknowledge a client's option negotiation request. + * The format of an OACK packet is: + * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + * | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | + * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + * + * opc + * The opcode field contains a 6, for Option Acknowledgment. + * + * opt1 + * The first option acknowledgment, copied from the original + * request. + * + * value1 + * The acknowledged value associated with the first option. If + * and how this value may differ from the original request is + * detailed in the specification for the option. + * + * optN, valueN + * The final option/value acknowledgment pair. + */ +static void +tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) +{ + /* + * We parse the OACK strings into an array + * of name-value pairs. + * + */ + char *tftp_options[128] = { 0 }; + char *val = buf; + int i = 0; + int option_idx = 0; + int blksize_is_set = 0; + int tsize = 0; + + + while ( option_idx < 128 && i < len ) { + if (buf[i] == '\0') { + if (&buf[i] > val) { + tftp_options[option_idx] = val; + val = &buf[i] + 1; + ++option_idx; + } + } + ++i; + } + + /* + * Parse individual TFTP options. + * * "blksize" is specified in RFC2348. + * * "tsize" is specified in RFC2349. + */ + for (i = 0; i < option_idx; i += 2) { + if (strcasecmp(tftp_options[i], "blksize") == 0) { + if (i + 1 < option_idx) { + blksize_is_set = + tftp_set_blksize(h, tftp_options[i + 1]); + } + } else if (strcasecmp(tftp_options[i], "tsize") == 0) { + if (i + 1 < option_idx) { + tsize = strtol(tftp_options[i + 1], (char **)NULL, 10); + } + } + } + + if (!blksize_is_set) { + /* + * If TFTP blksize was not set, try defaulting + * to the legacy TFTP blksize of 512 + */ + h->tftp_blksize = 512; + } + +#ifdef TFTP_DEBUG + printf("tftp_blksize: %u\n", h->tftp_blksize); + printf("tftp_tsize: %lu\n", h->tftp_tsize); +#endif +} Modified: projects/largeSMP/libexec/tftpd/tftpd.8 ============================================================================== --- projects/largeSMP/libexec/tftpd/tftpd.8 Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/libexec/tftpd/tftpd.8 Thu Jun 16 07:16:02 2011 (r223140) @@ -253,8 +253,9 @@ was introduced in support for the TFTP Blocksize Option (RFC2348) and the blksize2 option was introduced in .Fx 7.4 . -.Sh BUGS +.Sh NOTES Files larger than 33488896 octets (65535 blocks) cannot be transferred -without client and server supporting blocksize negotiation (RFC2348). +without client and server supporting the the TFTP blocksize option (RFC2348), +or the non-standard TFTP rollover option. .Pp Many tftp clients will not transfer files over 16744448 octets (32767 blocks). Modified: projects/largeSMP/release/Makefile ============================================================================== --- projects/largeSMP/release/Makefile Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/release/Makefile Thu Jun 16 07:16:02 2011 (r223140) @@ -110,8 +110,8 @@ reldoc: system: packagesystem # Install system -mkdir ${.OBJDIR}/release - cd ${WORLDDIR} && ${IMAKE} installkernel installworld distribution DESTDIR=${.OBJDIR}/release - -rm ${.OBJDIR}/release/boot/kernel/*.symbols + cd ${WORLDDIR} && ${IMAKE} installkernel installworld distribution \ + DESTDIR=${.OBJDIR}/release WITHOUT_RESCUE=1 WITHOUT_KERNEL_SYMBOLS=1 # Copy distfiles mkdir ${.OBJDIR}/release/usr/freebsd-dist cp ${.OBJDIR}/*.txz ${.OBJDIR}/MANIFEST \ @@ -135,8 +135,9 @@ bootonly: packagesystem WITHOUT_BIND_DNSSEC=1 WITHOUT_BIND_ETC=1 WITHOUT_BIND_MTREE=1 \ WITHOUT_BIND_NAMED=1 WITHOUT_GAMES=1 WITHOUT_GROFF=1 \ WITHOUT_INSTALLLIB=1 WITHOUT_LIB32=1 WITHOUT_MAIL=1 \ - WITHOUT_NCP=1 WITHOUT_TOOLCHAIN=1 WITHOUT_RESCUE=1 WITHOUT_DICT=1 - -rm ${.OBJDIR}/bootonly/boot/kernel/*.symbols + WITHOUT_NCP=1 WITHOUT_TOOLCHAIN=1 WITHOUT_PROFILE=1 \ + WITHOUT_INSTALLIB=1 WITHOUT_RESCUE=1 WITHOUT_DICT=1 \ + WITHOUT_KERNEL_SYMBOLS=1 # Copy manifest only (no distfiles) to get checksums mkdir ${.OBJDIR}/bootonly/usr/freebsd-dist cp ${.OBJDIR}/MANIFEST ${.OBJDIR}/bootonly/usr/freebsd-dist Modified: projects/largeSMP/sys/boot/forth/loader.rc ============================================================================== --- projects/largeSMP/sys/boot/forth/loader.rc Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/sys/boot/forth/loader.rc Thu Jun 16 07:16:02 2011 (r223140) @@ -10,8 +10,5 @@ start \ Tests for password -- executes autoboot first if a password was defined check-password -\ Load in the boot menu -include /boot/beastie.4th +\ Unless set otherwise, autoboot is automatic at this point -\ Start the boot menu -beastie-start Modified: projects/largeSMP/sys/conf/Makefile.arm ============================================================================== --- projects/largeSMP/sys/conf/Makefile.arm Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/sys/conf/Makefile.arm Thu Jun 16 07:16:02 2011 (r223140) @@ -108,7 +108,8 @@ ${KERNEL_KO}.tramp: ${KERNEL_KO} $S/$M/$ gzip -9 ${KERNEL_KO}.tmp eval $$(stat -s ${KERNEL_KO}.tmp.gz) && \ echo "#define KERNCOMPSIZE $$st_size" >>opt_kernname.h - ${CC} -O2 -DKZIP -I. -I$S -c $S/kern/inflate.c -o inflate-tramp.o + ${CC} -O2 -ffreestanding -DKZIP -I. -I$S -c $S/kern/inflate.c -o \ + inflate-tramp.o ${CC} -O -nostdlib -I. -I$S -Xlinker -T -Xlinker ldscript.$M.tramp \ -DKZIP tmphack.S $S/$M/$M/elf_trampoline.c inflate-tramp.o \ $S/$M/$M/inckern.S ${FILES_CPU_FUNC} -o ${KERNEL_KO}.gz.tramp Modified: projects/largeSMP/sys/dev/sound/pci/hda/hdac.c ============================================================================== --- projects/largeSMP/sys/dev/sound/pci/hda/hdac.c Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/sys/dev/sound/pci/hda/hdac.c Thu Jun 16 07:16:02 2011 (r223140) @@ -4146,7 +4146,10 @@ hdac_attach(device_t dev) uint16_t vendor; uint8_t v; - device_printf(dev, "HDA Driver Revision: %s\n", HDA_DRV_TEST_REV); + HDA_BOOTVERBOSE( + device_printf(dev, "HDA Driver Revision: %s\n", + HDA_DRV_TEST_REV); + ); model = (uint32_t)pci_get_device(dev) << 16; model |= (uint32_t)pci_get_vendor(dev) & 0x0000ffff; Modified: projects/largeSMP/sys/netinet/sctp.h ============================================================================== --- projects/largeSMP/sys/netinet/sctp.h Thu Jun 16 07:14:55 2011 (r223139) +++ projects/largeSMP/sys/netinet/sctp.h Thu Jun 16 07:16:02 2011 (r223140) @@ -91,7 +91,7 @@ struct sctp_paramhdr { #define SCTP_PEER_ADDR_PARAMS 0x0000000a #define SCTP_DEFAULT_SEND_PARAM 0x0000000b /* ancillary data/notification interest options */ -#define SCTP_EVENTS 0x0000000c +#define SCTP_EVENTS 0x0000000c /* deprecated */ /* Without this applied we will give V4 and V6 addresses on a V6 socket */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106160716.p5G7G3xR017185>